initial commit
This commit is contained in:
parent
e468202f95
commit
423b9a25fb
24 changed files with 6670 additions and 0 deletions
827
native/wordpress/maple-icons-wp/CLAUDE.MD
Normal file
827
native/wordpress/maple-icons-wp/CLAUDE.MD
Normal file
|
|
@ -0,0 +1,827 @@
|
||||||
|
# CLAUDE.md — Maple Icons WordPress Plugin
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
| Document | When to Reference |
|
||||||
|
|----------|-------------------|
|
||||||
|
| **CLAUDE.md** (this file) | Architecture, file structure, build order |
|
||||||
|
| **SECURITY.md** | Writing ANY PHP code (same patterns as Maple Local Fonts) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
Build a WordPress plugin called **Maple Icons** that:
|
||||||
|
1. Fetches open-source icon sets from CDN and stores them locally
|
||||||
|
2. Provides preset icon sets: Heroicons, Lucide, Feather, Phosphor, Material
|
||||||
|
3. Only ONE icon set can be active at a time (though multiple can be downloaded)
|
||||||
|
4. Offers a Gutenberg block "Maple Icons" for inserting icons
|
||||||
|
5. Icons use `currentColor` to inherit text color from Global Styles
|
||||||
|
|
||||||
|
**Key principle:** Download once, serve locally. Zero runtime external requests after initial fetch.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- **Minimum PHP:** 7.4
|
||||||
|
- **Minimum WordPress:** 6.5 (for block.json apiVersion 3 and Global Styles)
|
||||||
|
- **License:** GPL-2.0-or-later
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Preset Icon Sets
|
||||||
|
|
||||||
|
All icons fetched from jsdelivr CDN with pinned versions:
|
||||||
|
|
||||||
|
| Set | Package | Version | Styles | ~Icons | viewBox |
|
||||||
|
|-----|---------|---------|--------|--------|---------|
|
||||||
|
| Heroicons | `heroicons` | 2.1.1 | outline, solid, mini | 290 | 24×24 |
|
||||||
|
| Lucide | `lucide-static` | 0.303.0 | icons | 1,400 | 24×24 |
|
||||||
|
| Feather | `feather-icons` | 4.29.1 | icons | 280 | 24×24 |
|
||||||
|
| Phosphor | `@phosphor-icons/core` | 2.1.1 | regular, bold, light, thin, fill, duotone | 1,200× styles | 256×256 (normalize) |
|
||||||
|
| Material | `@material-design-icons/svg` | 0.14.13 | filled, outlined, round, sharp, two-tone | 2,500 | 24×24 |
|
||||||
|
|
||||||
|
### CDN URL Patterns
|
||||||
|
|
||||||
|
```
|
||||||
|
Heroicons: https://cdn.jsdelivr.net/npm/heroicons@2.1.1/24/outline/{name}.svg
|
||||||
|
Lucide: https://cdn.jsdelivr.net/npm/lucide-static@0.303.0/icons/{name}.svg
|
||||||
|
Feather: https://cdn.jsdelivr.net/npm/feather-icons@4.29.1/dist/icons/{name}.svg
|
||||||
|
Phosphor: https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2.1.1/assets/{style}/{name}.svg
|
||||||
|
Material: https://cdn.jsdelivr.net/npm/@material-design-icons/svg@0.14.13/{style}/{name}.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
### SVG Normalization Required
|
||||||
|
|
||||||
|
| Set | Issue | Fix |
|
||||||
|
|-----|-------|-----|
|
||||||
|
| Phosphor | viewBox="0 0 256 256" | Normalize to 24×24 |
|
||||||
|
| Material | `fill="#000000"` hardcoded | Replace with `currentColor` |
|
||||||
|
| All | May have XML declarations, comments | Strip during save |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## User Flow
|
||||||
|
|
||||||
|
```
|
||||||
|
Admin visits Settings → Maple Icons (or plugin action link)
|
||||||
|
↓
|
||||||
|
Sees list of preset icon sets with Download/Delete buttons
|
||||||
|
↓
|
||||||
|
Clicks "Download" on Heroicons → progress bar → icons saved locally
|
||||||
|
↓
|
||||||
|
Clicks "Set Active" to make Heroicons the active set
|
||||||
|
↓
|
||||||
|
User inserts "Maple Icons" block in Gutenberg editor
|
||||||
|
↓
|
||||||
|
Block shows + button → click → icon picker modal with search
|
||||||
|
↓
|
||||||
|
User searches/filters → selects icon → SVG inserted inline
|
||||||
|
↓
|
||||||
|
SVG uses currentColor → inherits from Global Styles
|
||||||
|
↓
|
||||||
|
All icons served from local storage (wp-content/maple-icons/)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
maple-icons-wp/
|
||||||
|
├── maple-icons.php # Main plugin file
|
||||||
|
├── index.php # Silence is golden
|
||||||
|
├── uninstall.php # Clean removal
|
||||||
|
├── readme.txt # WordPress.org readme
|
||||||
|
├── package.json # Block build config
|
||||||
|
├── includes/
|
||||||
|
│ ├── index.php
|
||||||
|
│ ├── class-mi-icon-sets.php # Preset icon set definitions
|
||||||
|
│ ├── class-mi-icon-registry.php # Icon management & search
|
||||||
|
│ ├── class-mi-downloader.php # CDN fetch & local storage
|
||||||
|
│ ├── class-mi-admin-page.php # Settings page
|
||||||
|
│ └── class-mi-ajax-handler.php # AJAX handlers
|
||||||
|
├── presets/ # Bundled manifests (icon names, tags)
|
||||||
|
│ ├── index.php
|
||||||
|
│ ├── heroicons.json
|
||||||
|
│ ├── lucide.json
|
||||||
|
│ ├── feather.json
|
||||||
|
│ ├── phosphor.json
|
||||||
|
│ └── material.json
|
||||||
|
├── build/ # Compiled block assets (generated)
|
||||||
|
│ ├── index.php
|
||||||
|
│ ├── index.js
|
||||||
|
│ ├── index.asset.php
|
||||||
|
│ └── style-index.css
|
||||||
|
├── src/ # Block source (for development)
|
||||||
|
│ ├── index.js # Block registration
|
||||||
|
│ ├── edit.js # Editor component
|
||||||
|
│ ├── save.js # Save component (inline SVG)
|
||||||
|
│ ├── icon-picker.js # Icon selection modal
|
||||||
|
│ ├── editor.scss # Editor-only styles
|
||||||
|
│ └── block.json # Block metadata
|
||||||
|
├── assets/
|
||||||
|
│ ├── index.php
|
||||||
|
│ ├── admin.css # Settings page styles
|
||||||
|
│ └── admin.js # Settings page JS (download progress, etc.)
|
||||||
|
└── languages/
|
||||||
|
├── index.php
|
||||||
|
└── maple-icons.pot
|
||||||
|
```
|
||||||
|
|
||||||
|
### Local Icon Storage
|
||||||
|
|
||||||
|
Icons are stored in:
|
||||||
|
```
|
||||||
|
wp-content/maple-icons/{set-slug}/{style}/{icon-name}.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
Example:
|
||||||
|
```
|
||||||
|
wp-content/maple-icons/heroicons/outline/academic-cap.svg
|
||||||
|
wp-content/maple-icons/heroicons/solid/academic-cap.svg
|
||||||
|
wp-content/maple-icons/lucide/icons/activity.svg
|
||||||
|
wp-content/maple-icons/phosphor/regular/airplane.svg
|
||||||
|
```
|
||||||
|
|
||||||
|
Using `wp-content/maple-icons/` (not uploads) to avoid cleanup plugin interference.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Class Responsibilities
|
||||||
|
|
||||||
|
### MI_Icon_Sets
|
||||||
|
Static definitions of all preset icon sets.
|
||||||
|
|
||||||
|
```php
|
||||||
|
class MI_Icon_Sets {
|
||||||
|
public static function get_all(): array;
|
||||||
|
public static function get(string $slug): ?array;
|
||||||
|
public static function get_cdn_url(string $slug, string $style, string $name): string;
|
||||||
|
public static function get_manifest_path(string $slug): string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Returns structure:
|
||||||
|
```php
|
||||||
|
[
|
||||||
|
'slug' => 'heroicons',
|
||||||
|
'name' => 'Heroicons',
|
||||||
|
'version' => '2.1.1',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'url' => 'https://heroicons.com',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/heroicons@2.1.1/',
|
||||||
|
'styles' => [
|
||||||
|
'outline' => ['path' => '24/outline', 'label' => 'Outline'],
|
||||||
|
'solid' => ['path' => '24/solid', 'label' => 'Solid'],
|
||||||
|
'mini' => ['path' => '20/solid', 'label' => 'Mini'],
|
||||||
|
],
|
||||||
|
'default_style' => 'outline',
|
||||||
|
'viewbox' => '0 0 24 24',
|
||||||
|
'normalize' => false, // true for Phosphor (256→24)
|
||||||
|
'color_fix' => false, // true for Material (replace hardcoded colors)
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### MI_Icon_Registry
|
||||||
|
Manages downloaded sets and provides icon search/retrieval.
|
||||||
|
|
||||||
|
```php
|
||||||
|
class MI_Icon_Registry {
|
||||||
|
public function get_downloaded_sets(): array;
|
||||||
|
public function get_active_set(): ?string;
|
||||||
|
public function set_active(string $slug): bool;
|
||||||
|
public function is_downloaded(string $slug): bool;
|
||||||
|
public function get_icons_for_set(string $slug, string $style): array;
|
||||||
|
public function search_icons(string $query, int $limit = 50): array;
|
||||||
|
public function get_icon_svg(string $slug, string $style, string $name): string|WP_Error;
|
||||||
|
public function delete_set(string $slug): bool;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MI_Downloader
|
||||||
|
Handles fetching icons from CDN and storing locally.
|
||||||
|
|
||||||
|
```php
|
||||||
|
class MI_Downloader {
|
||||||
|
public function download_set(string $slug, callable $progress_callback = null): array|WP_Error;
|
||||||
|
public function download_icon(string $slug, string $style, string $name): string|WP_Error;
|
||||||
|
private function normalize_svg(string $svg, array $set_config): string;
|
||||||
|
private function get_local_path(string $slug, string $style, string $name): string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### MI_Admin_Page
|
||||||
|
Settings page under Settings → Maple Icons.
|
||||||
|
|
||||||
|
- List all preset icon sets
|
||||||
|
- Show download status (downloaded/not downloaded)
|
||||||
|
- Download button with progress indicator
|
||||||
|
- Delete button for downloaded sets
|
||||||
|
- Radio buttons to select active set
|
||||||
|
- Preview sample icons from each downloaded set
|
||||||
|
|
||||||
|
### MI_Ajax_Handler
|
||||||
|
AJAX endpoints:
|
||||||
|
|
||||||
|
- `mi_download_set` — Download an icon set from CDN
|
||||||
|
- `mi_delete_set` — Delete a downloaded icon set
|
||||||
|
- `mi_set_active` — Set the active icon set
|
||||||
|
- `mi_search_icons` — Search icons in active set (for block picker)
|
||||||
|
- `mi_get_icon_svg` — Get specific icon SVG (for block)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Settings Storage
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Option name: maple_icons_settings
|
||||||
|
[
|
||||||
|
'active_set' => 'heroicons', // Slug of active set, or empty string
|
||||||
|
'downloaded_sets' => [
|
||||||
|
'heroicons' => [
|
||||||
|
'version' => '2.1.1',
|
||||||
|
'downloaded_at' => '2024-01-15 10:30:00',
|
||||||
|
'icon_count' => 876, // Total across all styles
|
||||||
|
],
|
||||||
|
'lucide' => [
|
||||||
|
'version' => '0.303.0',
|
||||||
|
'downloaded_at' => '2024-01-15 11:00:00',
|
||||||
|
'icon_count' => 1400,
|
||||||
|
],
|
||||||
|
],
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Manifest Format (presets/*.json)
|
||||||
|
|
||||||
|
Each preset ships with a manifest listing all icons:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"slug": "heroicons",
|
||||||
|
"name": "Heroicons",
|
||||||
|
"version": "2.1.1",
|
||||||
|
"icons": [
|
||||||
|
{
|
||||||
|
"name": "academic-cap",
|
||||||
|
"tags": ["education", "graduation", "school", "hat"],
|
||||||
|
"category": "objects",
|
||||||
|
"styles": ["outline", "solid", "mini"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "adjustments-horizontal",
|
||||||
|
"tags": ["settings", "controls", "sliders"],
|
||||||
|
"category": "ui",
|
||||||
|
"styles": ["outline", "solid", "mini"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Manifests are bundled with the plugin to avoid runtime dependency on jsdelivr API.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gutenberg Block Architecture
|
||||||
|
|
||||||
|
### Block Registration (block.json)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"$schema": "https://schemas.wp.org/trunk/block.json",
|
||||||
|
"apiVersion": 3,
|
||||||
|
"name": "jetrails/maple-icons",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"title": "Maple Icons",
|
||||||
|
"category": "design",
|
||||||
|
"icon": "star-filled",
|
||||||
|
"description": "Insert an icon from your downloaded icon sets.",
|
||||||
|
"keywords": ["icon", "svg", "symbol", "maple"],
|
||||||
|
"textdomain": "maple-icons",
|
||||||
|
"attributes": {
|
||||||
|
"iconSet": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"iconStyle": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"iconName": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"iconSVG": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"size": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 24
|
||||||
|
},
|
||||||
|
"label": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
},
|
||||||
|
"strokeWidth": {
|
||||||
|
"type": "number",
|
||||||
|
"default": 0
|
||||||
|
},
|
||||||
|
"strokeColor": {
|
||||||
|
"type": "string",
|
||||||
|
"default": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports": {
|
||||||
|
"html": false,
|
||||||
|
"align": ["left", "center", "right"],
|
||||||
|
"color": {
|
||||||
|
"text": true,
|
||||||
|
"background": true,
|
||||||
|
"gradients": true
|
||||||
|
},
|
||||||
|
"spacing": {
|
||||||
|
"margin": true,
|
||||||
|
"padding": true
|
||||||
|
},
|
||||||
|
"shadow": true
|
||||||
|
},
|
||||||
|
"editorScript": "file:./index.js",
|
||||||
|
"editorStyle": "file:./style-index.css"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Block Style Controls (Inspector Panel)
|
||||||
|
|
||||||
|
The block sidebar will include these controls:
|
||||||
|
|
||||||
|
**Icon Settings:**
|
||||||
|
- Icon picker button (change icon)
|
||||||
|
- Size slider (8-256px, default 24)
|
||||||
|
- Accessibility label text input
|
||||||
|
|
||||||
|
**Color Settings (via WordPress supports):**
|
||||||
|
- Icon color (text color) — inherited by SVG via `currentColor`
|
||||||
|
- Background color
|
||||||
|
- Gradient support
|
||||||
|
|
||||||
|
**Stroke Settings (custom panel):**
|
||||||
|
- Stroke width slider (0-10px)
|
||||||
|
- Stroke color picker
|
||||||
|
|
||||||
|
**Spacing (via WordPress supports):**
|
||||||
|
- Padding controls
|
||||||
|
- Margin controls
|
||||||
|
|
||||||
|
**Effects:**
|
||||||
|
- Drop shadow presets (via WordPress `shadow` support)
|
||||||
|
|
||||||
|
### Style Application
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// In edit.js and save.js, compute styles:
|
||||||
|
const iconStyles = {
|
||||||
|
width: `${size}px`,
|
||||||
|
height: `${size}px`,
|
||||||
|
display: 'inline-flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
};
|
||||||
|
|
||||||
|
// Stroke is applied via CSS filter or SVG manipulation
|
||||||
|
const svgStyles = strokeWidth > 0 ? {
|
||||||
|
filter: `drop-shadow(0 0 0 ${strokeColor})`,
|
||||||
|
WebkitTextStroke: `${strokeWidth}px ${strokeColor}`,
|
||||||
|
} : {};
|
||||||
|
|
||||||
|
// Note: For true SVG stroke, we modify the SVG's stroke attribute
|
||||||
|
// This is handled in the SVG wrapper, not CSS
|
||||||
|
```
|
||||||
|
|
||||||
|
### SVG Stroke Handling
|
||||||
|
|
||||||
|
For stroke on SVG icons, we wrap the SVG output:
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
// The SVG itself uses currentColor for fill/stroke
|
||||||
|
// Additional stroke effect applied via CSS or inline style
|
||||||
|
<span
|
||||||
|
className="wp-block-maple-icon__svg"
|
||||||
|
style={{
|
||||||
|
// Apply stroke via paint-order and stroke properties
|
||||||
|
'--mi-stroke-width': strokeWidth ? `${strokeWidth}px` : undefined,
|
||||||
|
'--mi-stroke-color': strokeColor || undefined,
|
||||||
|
}}
|
||||||
|
dangerouslySetInnerHTML={{ __html: iconSVG }}
|
||||||
|
/>
|
||||||
|
```
|
||||||
|
|
||||||
|
With CSS:
|
||||||
|
```css
|
||||||
|
.wp-block-maple-icon__svg svg {
|
||||||
|
stroke: var(--mi-stroke-color, currentColor);
|
||||||
|
stroke-width: var(--mi-stroke-width, 0);
|
||||||
|
paint-order: stroke fill;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Block Behavior
|
||||||
|
|
||||||
|
**Initial State (no icon selected):**
|
||||||
|
- Shows + button placeholder
|
||||||
|
- Click opens icon picker modal
|
||||||
|
|
||||||
|
**With icon selected:**
|
||||||
|
- Displays inline SVG
|
||||||
|
- Sidebar shows: size control, accessibility label, change icon button
|
||||||
|
|
||||||
|
**Icon Picker Modal:**
|
||||||
|
- Search input (filters as you type)
|
||||||
|
- Style selector dropdown (if set has multiple styles)
|
||||||
|
- Grid of icon thumbnails
|
||||||
|
- Click to select → SVG fetched and stored in attributes
|
||||||
|
|
||||||
|
### Save Output (save.js)
|
||||||
|
|
||||||
|
```jsx
|
||||||
|
export default function save({ attributes }) {
|
||||||
|
const { iconSVG, size, label } = attributes;
|
||||||
|
|
||||||
|
if (!iconSVG) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const blockProps = useBlockProps.save({
|
||||||
|
className: 'wp-block-maple-icon',
|
||||||
|
style: {
|
||||||
|
width: `${size}px`,
|
||||||
|
height: `${size}px`,
|
||||||
|
display: 'inline-flex',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<span {...blockProps}>
|
||||||
|
<span
|
||||||
|
dangerouslySetInnerHTML={{ __html: iconSVG }}
|
||||||
|
role={label ? 'img' : 'presentation'}
|
||||||
|
aria-label={label || undefined}
|
||||||
|
aria-hidden={!label ? 'true' : undefined}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Download Process
|
||||||
|
|
||||||
|
### Batch Download Flow
|
||||||
|
|
||||||
|
1. User clicks "Download" for an icon set
|
||||||
|
2. Frontend disables button, shows progress bar
|
||||||
|
3. AJAX request to `mi_download_set`
|
||||||
|
4. Backend:
|
||||||
|
a. Load manifest from `presets/{slug}.json`
|
||||||
|
b. Create local directory structure
|
||||||
|
c. For each icon in manifest:
|
||||||
|
- Fetch SVG from CDN
|
||||||
|
- Normalize (viewBox, currentColor)
|
||||||
|
- Save to local filesystem
|
||||||
|
d. Update settings with download info
|
||||||
|
5. Return success with icon count
|
||||||
|
6. Frontend updates UI to show "Downloaded" state
|
||||||
|
|
||||||
|
### Batching Strategy
|
||||||
|
|
||||||
|
To avoid timeouts and memory issues:
|
||||||
|
- Process icons in batches of 50
|
||||||
|
- Use streaming/chunked approach
|
||||||
|
- Allow resume on failure (track progress in transient)
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Download in batches
|
||||||
|
$batch_size = 50;
|
||||||
|
$icons = $manifest['icons'];
|
||||||
|
$total = count($icons);
|
||||||
|
|
||||||
|
for ($i = 0; $i < $total; $i += $batch_size) {
|
||||||
|
$batch = array_slice($icons, $i, $batch_size);
|
||||||
|
foreach ($batch as $icon) {
|
||||||
|
// Download each icon in batch
|
||||||
|
}
|
||||||
|
// Update progress transient
|
||||||
|
set_transient('mi_download_progress_' . $slug, [
|
||||||
|
'completed' => min($i + $batch_size, $total),
|
||||||
|
'total' => $total,
|
||||||
|
], HOUR_IN_SECONDS);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## SVG Sanitization
|
||||||
|
|
||||||
|
Same approach as original CLAUDE.md — strict allowlist of SVG elements and attributes.
|
||||||
|
|
||||||
|
```php
|
||||||
|
function mi_sanitize_svg($svg) {
|
||||||
|
$allowed_tags = [
|
||||||
|
'svg' => ['xmlns', 'viewbox', 'width', 'height', 'fill', 'stroke', ...],
|
||||||
|
'path' => ['d', 'fill', 'stroke', 'stroke-width', ...],
|
||||||
|
'circle' => ['cx', 'cy', 'r', 'fill', 'stroke', ...],
|
||||||
|
'rect' => ['x', 'y', 'width', 'height', 'rx', 'ry', ...],
|
||||||
|
'line' => ['x1', 'y1', 'x2', 'y2', ...],
|
||||||
|
'polyline' => ['points', ...],
|
||||||
|
'polygon' => ['points', ...],
|
||||||
|
'ellipse' => ['cx', 'cy', 'rx', 'ry', ...],
|
||||||
|
'g' => ['fill', 'stroke', 'transform', ...],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Remove dangerous content
|
||||||
|
$svg = preg_replace('/<script\b[^>]*>.*?<\/script>/is', '', $svg);
|
||||||
|
$svg = preg_replace('/\son\w+\s*=/i', ' data-removed=', $svg);
|
||||||
|
|
||||||
|
return wp_kses($svg, $allowed_tags);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### SVG Normalization
|
||||||
|
|
||||||
|
```php
|
||||||
|
function mi_normalize_svg($svg, $set_config) {
|
||||||
|
// 1. Strip XML declaration
|
||||||
|
$svg = preg_replace('/<\?xml[^>]*\?>/i', '', $svg);
|
||||||
|
|
||||||
|
// 2. Strip comments
|
||||||
|
$svg = preg_replace('/<!--.*?-->/s', '', $svg);
|
||||||
|
|
||||||
|
// 3. Normalize viewBox for Phosphor (256 → 24)
|
||||||
|
if ($set_config['normalize']) {
|
||||||
|
$svg = preg_replace('/viewBox=["\']0 0 256 256["\']/', 'viewBox="0 0 24 24"', $svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Fix hardcoded colors for Material
|
||||||
|
if ($set_config['color_fix']) {
|
||||||
|
$svg = preg_replace('/fill=["\']#[0-9a-fA-F]{3,6}["\']/', 'fill="currentColor"', $svg);
|
||||||
|
$svg = preg_replace('/fill=["\']black["\']/', 'fill="currentColor"', $svg);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Ensure currentColor is used
|
||||||
|
// Most sets already use currentColor, but double-check
|
||||||
|
|
||||||
|
// 6. Remove width/height attributes (let CSS control)
|
||||||
|
$svg = preg_replace('/\s(width|height)=["\'][^"\']*["\']/', '', $svg);
|
||||||
|
|
||||||
|
return trim($svg);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Admin Settings Page UI
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Maple Icons │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ ICON SETS │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ ◉ Heroicons ✓ Downloaded │ │
|
||||||
|
│ │ 290 icons · Outline, Solid, Mini · MIT │ │
|
||||||
|
│ │ [Preview: ⚙ 🏠 👤 ✉ 🔔 ⭐] │ │
|
||||||
|
│ │ [Delete] │ │
|
||||||
|
│ ├─────────────────────────────────────────────────────────────┤ │
|
||||||
|
│ │ ○ Lucide ✓ Downloaded │ │
|
||||||
|
│ │ 1,400 icons · Icons · ISC │ │
|
||||||
|
│ │ [Preview: ⚙ 📁 📄 💾 🖨 ⬇] │ │
|
||||||
|
│ │ [Delete] │ │
|
||||||
|
│ ├─────────────────────────────────────────────────────────────┤ │
|
||||||
|
│ │ ○ Feather Not downloaded │ │
|
||||||
|
│ │ 280 icons · Icons · MIT │ │
|
||||||
|
│ │ [Download] │ │
|
||||||
|
│ ├─────────────────────────────────────────────────────────────┤ │
|
||||||
|
│ │ ○ Phosphor Not downloaded │ │
|
||||||
|
│ │ 7,200 icons · 6 styles · MIT │ │
|
||||||
|
│ │ [Download] │ │
|
||||||
|
│ ├─────────────────────────────────────────────────────────────┤ │
|
||||||
|
│ │ ○ Material Not downloaded │ │
|
||||||
|
│ │ 2,500 icons · 5 styles · Apache 2.0 │ │
|
||||||
|
│ │ [Download] │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ ◉ = Active icon set (used in Maple Icons block) │
|
||||||
|
│ │
|
||||||
|
│ ─────────────────────────────────────────────────────────────── │
|
||||||
|
│ │
|
||||||
|
│ USAGE │
|
||||||
|
│ 1. Download one or more icon sets above │
|
||||||
|
│ 2. Select which set should be active (radio button) │
|
||||||
|
│ 3. Insert icons using the "Maple Icons" block in the editor │
|
||||||
|
│ 4. Icons inherit your theme's text color automatically │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Icon Picker Modal (Block Editor)
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ Select Icon [X] │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ 🔍 Search icons... │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ Style: [Outline ▼] │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||||
|
│ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ │
|
||||||
|
│ │ │ ⚙ │ │ 🏠 │ │ 👤 │ │ ✉ │ │ 🔔 │ │ ⭐ │ │ ❤ │ │ 🔍 │ │ │
|
||||||
|
│ │ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ │ │
|
||||||
|
│ │ cog home user mail bell star heart search │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ ┌───┐ │ │
|
||||||
|
│ │ │ + │ │ ✓ │ │ ✕ │ │ ⬆ │ │ ⬇ │ │ ◀ │ │ ▶ │ │ ↻ │ │ │
|
||||||
|
│ │ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ └───┘ │ │
|
||||||
|
│ │ plus check x up down left right refresh │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ [Load More...] │ │
|
||||||
|
│ └─────────────────────────────────────────────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ Selected: arrow-right │
|
||||||
|
│ │
|
||||||
|
│ [Cancel] [Insert Icon] │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Build Order
|
||||||
|
|
||||||
|
### Phase 1: Foundation
|
||||||
|
1. `maple-icons.php` — Plugin header, constants, autoloader, activation hook
|
||||||
|
2. `index.php` files in ALL directories
|
||||||
|
3. `includes/class-mi-icon-sets.php` — Static preset definitions
|
||||||
|
|
||||||
|
### Phase 2: Download Infrastructure
|
||||||
|
4. `includes/class-mi-downloader.php` — CDN fetch, normalize, store
|
||||||
|
5. `includes/class-mi-icon-registry.php` — Downloaded set management
|
||||||
|
6. `includes/class-mi-ajax-handler.php` — Download/delete/activate endpoints
|
||||||
|
7. Create manifest files: `presets/*.json`
|
||||||
|
|
||||||
|
### Phase 3: Admin Interface
|
||||||
|
8. `includes/class-mi-admin-page.php` — Settings page
|
||||||
|
9. `assets/admin.css` — Settings page styles
|
||||||
|
10. `assets/admin.js` — Download progress, AJAX handlers
|
||||||
|
|
||||||
|
### Phase 4: Gutenberg Block
|
||||||
|
11. `src/block.json` — Block metadata
|
||||||
|
12. `src/index.js` — Block registration
|
||||||
|
13. `src/edit.js` — Editor component
|
||||||
|
14. `src/save.js` — Save component
|
||||||
|
15. `src/icon-picker.js` — Modal component
|
||||||
|
16. `src/editor.scss` — Editor styles
|
||||||
|
17. `package.json` + build
|
||||||
|
|
||||||
|
### Phase 5: Cleanup & Polish
|
||||||
|
18. `uninstall.php` — Clean removal
|
||||||
|
19. `readme.txt` — WordPress.org readme
|
||||||
|
20. Testing
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Constants
|
||||||
|
|
||||||
|
```php
|
||||||
|
define('MI_VERSION', '1.0.0');
|
||||||
|
define('MI_PLUGIN_DIR', plugin_dir_path(__FILE__));
|
||||||
|
define('MI_PLUGIN_URL', plugin_dir_url(__FILE__));
|
||||||
|
define('MI_PLUGIN_BASENAME', plugin_basename(__FILE__));
|
||||||
|
define('MI_ICONS_DIR', WP_CONTENT_DIR . '/maple-icons/');
|
||||||
|
define('MI_ICONS_URL', content_url('/maple-icons/'));
|
||||||
|
define('MI_PRESETS_DIR', MI_PLUGIN_DIR . 'presets/');
|
||||||
|
|
||||||
|
// Limits
|
||||||
|
define('MI_DOWNLOAD_BATCH_SIZE', 50);
|
||||||
|
define('MI_SEARCH_LIMIT', 50);
|
||||||
|
define('MI_DOWNLOAD_TIMEOUT', 10); // Per-icon timeout in seconds
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Checklist
|
||||||
|
|
||||||
|
Reference SECURITY.md for full details. Key points:
|
||||||
|
|
||||||
|
- [ ] ABSPATH check on every PHP file
|
||||||
|
- [ ] index.php in every directory
|
||||||
|
- [ ] Nonce verification FIRST in every AJAX handler
|
||||||
|
- [ ] Capability check SECOND (`manage_options` for settings, `edit_posts` for block)
|
||||||
|
- [ ] Validate icon set slugs against preset allowlist
|
||||||
|
- [ ] Validate style slugs against set's defined styles
|
||||||
|
- [ ] Sanitize all SVG content before storage
|
||||||
|
- [ ] Validate file paths (prevent path traversal)
|
||||||
|
- [ ] Use `wp_remote_get()` for CDN requests
|
||||||
|
- [ ] Escape all output
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WordPress Hooks Used
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Activation/Deactivation
|
||||||
|
register_activation_hook(__FILE__, 'mi_activate');
|
||||||
|
register_deactivation_hook(__FILE__, 'mi_deactivate');
|
||||||
|
|
||||||
|
// Block registration
|
||||||
|
add_action('init', 'mi_register_block');
|
||||||
|
|
||||||
|
// Admin menu
|
||||||
|
add_action('admin_menu', 'mi_register_settings_page');
|
||||||
|
|
||||||
|
// Admin assets (settings page only)
|
||||||
|
add_action('admin_enqueue_scripts', 'mi_enqueue_admin_assets');
|
||||||
|
|
||||||
|
// Plugin action links (Settings link in plugin list)
|
||||||
|
add_filter('plugin_action_links_' . MI_PLUGIN_BASENAME, 'mi_add_action_links');
|
||||||
|
|
||||||
|
// AJAX handlers (admin only)
|
||||||
|
add_action('wp_ajax_mi_download_set', 'mi_ajax_download_set');
|
||||||
|
add_action('wp_ajax_mi_delete_set', 'mi_ajax_delete_set');
|
||||||
|
add_action('wp_ajax_mi_set_active', 'mi_ajax_set_active');
|
||||||
|
add_action('wp_ajax_mi_search_icons', 'mi_ajax_search_icons');
|
||||||
|
add_action('wp_ajax_mi_get_icon_svg', 'mi_ajax_get_icon_svg');
|
||||||
|
|
||||||
|
// WooCommerce HPOS compatibility
|
||||||
|
add_action('before_woocommerce_init', 'mi_declare_hpos_compatibility');
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Compatibility Notes
|
||||||
|
|
||||||
|
### WooCommerce HPOS
|
||||||
|
Declare compatibility (we don't touch orders):
|
||||||
|
```php
|
||||||
|
add_action('before_woocommerce_init', function() {
|
||||||
|
if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
|
||||||
|
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
|
||||||
|
'custom_order_tables',
|
||||||
|
__FILE__,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Caching Plugins
|
||||||
|
Icons stored locally means no cache issues. SVG is inline in post_content.
|
||||||
|
|
||||||
|
### Wordfence
|
||||||
|
CDN requests only happen during admin download action, using standard `wp_remote_get()`.
|
||||||
|
|
||||||
|
### LearnDash / WPForms
|
||||||
|
No interference — we only add a block, no frontend hooks.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Checklist
|
||||||
|
|
||||||
|
### Download Flow
|
||||||
|
- [ ] Download Heroicons → all icons saved locally
|
||||||
|
- [ ] Download progress shows correctly
|
||||||
|
- [ ] Download Lucide (large set) → doesn't timeout
|
||||||
|
- [ ] Delete downloaded set → files removed
|
||||||
|
- [ ] Switch active set → setting persists
|
||||||
|
|
||||||
|
### Block Editor
|
||||||
|
- [ ] Insert Maple Icons block → shows placeholder
|
||||||
|
- [ ] Click + → opens icon picker
|
||||||
|
- [ ] Search filters icons correctly
|
||||||
|
- [ ] Style dropdown works (for sets with multiple styles)
|
||||||
|
- [ ] Select icon → SVG appears in editor
|
||||||
|
- [ ] Save post → icon persists
|
||||||
|
- [ ] Frontend → icon displays correctly
|
||||||
|
- [ ] Change text color in Global Styles → icon color changes
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- [ ] Download without nonce → 403
|
||||||
|
- [ ] Download as non-admin → 403
|
||||||
|
- [ ] Invalid set slug → rejected
|
||||||
|
- [ ] Path traversal attempt → rejected
|
||||||
|
|
||||||
|
### Edge Cases
|
||||||
|
- [ ] No sets downloaded → block shows helpful message
|
||||||
|
- [ ] Active set deleted → block handles gracefully
|
||||||
|
- [ ] CDN unreachable during download → appropriate error
|
||||||
|
- [ ] Partial download failure → can retry/resume
|
||||||
621
native/wordpress/maple-icons-wp/SECURITY.md
Normal file
621
native/wordpress/maple-icons-wp/SECURITY.md
Normal file
|
|
@ -0,0 +1,621 @@
|
||||||
|
# SECURITY.md — Maple Local Fonts Security Requirements
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document covers all security requirements for the Maple Local Fonts plugin. Reference this when writing ANY PHP code.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ABSPATH Check (Every PHP File)
|
||||||
|
|
||||||
|
Every PHP file MUST start with this check. No exceptions.
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Silence is Golden Files
|
||||||
|
|
||||||
|
Create `index.php` in EVERY directory:
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Required locations:**
|
||||||
|
- `/maple-local-fonts/index.php`
|
||||||
|
- `/maple-local-fonts/includes/index.php`
|
||||||
|
- `/maple-local-fonts/assets/index.php`
|
||||||
|
- `/maple-local-fonts/languages/index.php`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OWASP Compliance
|
||||||
|
|
||||||
|
### A1 - Injection Prevention
|
||||||
|
|
||||||
|
**SQL Injection:**
|
||||||
|
```php
|
||||||
|
// NEVER do this
|
||||||
|
$wpdb->query("SELECT * FROM table WHERE id = " . $_POST['id']);
|
||||||
|
|
||||||
|
// ALWAYS do this
|
||||||
|
$wpdb->get_results($wpdb->prepare(
|
||||||
|
"SELECT * FROM %i WHERE id = %d",
|
||||||
|
$table_name,
|
||||||
|
absint($_POST['id'])
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** This plugin should rarely need direct SQL. Use WordPress APIs (`get_posts`, `wp_insert_post`, etc.) which handle escaping internally.
|
||||||
|
|
||||||
|
### A2 - Authentication
|
||||||
|
|
||||||
|
All admin actions require capability check:
|
||||||
|
|
||||||
|
```php
|
||||||
|
if (!current_user_can('edit_theme_options')) {
|
||||||
|
wp_die('Unauthorized', 'Error', ['response' => 403]);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### A3 - Sensitive Data
|
||||||
|
|
||||||
|
- No API keys (Google Fonts CSS2 API is public)
|
||||||
|
- No user credentials stored
|
||||||
|
- No PII collected
|
||||||
|
|
||||||
|
### A5 - Broken Access Control
|
||||||
|
|
||||||
|
**Order of checks for ALL AJAX handlers:**
|
||||||
|
|
||||||
|
```php
|
||||||
|
public function handle_ajax_action() {
|
||||||
|
// 1. Nonce verification FIRST
|
||||||
|
if (!check_ajax_referer('mlf_action_name', 'nonce', false)) {
|
||||||
|
wp_send_json_error(['message' => 'Security check failed'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check SECOND
|
||||||
|
if (!current_user_can('edit_theme_options')) {
|
||||||
|
wp_send_json_error(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation THIRD
|
||||||
|
// ... validate all inputs ...
|
||||||
|
|
||||||
|
// 4. Process request
|
||||||
|
// ... actual logic ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### A7 - Cross-Site Scripting (XSS)
|
||||||
|
|
||||||
|
**Escape ALL output:**
|
||||||
|
|
||||||
|
```php
|
||||||
|
// HTML content
|
||||||
|
echo esc_html($font_name);
|
||||||
|
|
||||||
|
// HTML attributes
|
||||||
|
echo '<input value="' . esc_attr($font_name) . '">';
|
||||||
|
|
||||||
|
// URLs
|
||||||
|
echo '<a href="' . esc_url($url) . '">';
|
||||||
|
|
||||||
|
// JavaScript data
|
||||||
|
wp_localize_script('mlf-admin', 'mlfData', [
|
||||||
|
'fontName' => esc_js($font_name), // Or let wp_localize_script handle it
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Translatable strings with variables
|
||||||
|
printf(
|
||||||
|
esc_html__('Installed: %s', 'maple-local-fonts'),
|
||||||
|
esc_html($font_name)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Never trust input for output:**
|
||||||
|
```php
|
||||||
|
// WRONG - XSS vulnerability
|
||||||
|
echo '<div>' . $_POST['font_name'] . '</div>';
|
||||||
|
|
||||||
|
// RIGHT - sanitize input, escape output
|
||||||
|
$font_name = sanitize_text_field($_POST['font_name']);
|
||||||
|
echo '<div>' . esc_html($font_name) . '</div>';
|
||||||
|
```
|
||||||
|
|
||||||
|
### A8 - Insecure Deserialization
|
||||||
|
|
||||||
|
```php
|
||||||
|
// NEVER use unserialize() on external data
|
||||||
|
$data = unserialize($_POST['data']); // DANGEROUS
|
||||||
|
|
||||||
|
// Use JSON instead
|
||||||
|
$data = json_decode(sanitize_text_field($_POST['data']), true);
|
||||||
|
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||||
|
wp_send_json_error(['message' => 'Invalid data format']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### A9 - Vulnerable Components
|
||||||
|
|
||||||
|
- No external PHP libraries
|
||||||
|
- Use only WordPress core functions
|
||||||
|
- Keep dependencies to zero
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Nonce Implementation
|
||||||
|
|
||||||
|
### Creating Nonces
|
||||||
|
|
||||||
|
**In admin page form:**
|
||||||
|
```php
|
||||||
|
wp_nonce_field('mlf_download_font', 'mlf_nonce');
|
||||||
|
```
|
||||||
|
|
||||||
|
**For AJAX (via wp_localize_script):**
|
||||||
|
```php
|
||||||
|
wp_localize_script('mlf-admin', 'mlfData', [
|
||||||
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
||||||
|
'nonce' => wp_create_nonce('mlf_download_font'),
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verifying Nonces
|
||||||
|
|
||||||
|
**AJAX handler:**
|
||||||
|
```php
|
||||||
|
// Returns false on failure, doesn't die (we handle response ourselves)
|
||||||
|
if (!check_ajax_referer('mlf_download_font', 'nonce', false)) {
|
||||||
|
wp_send_json_error(['message' => 'Security check failed'], 403);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Form submission:**
|
||||||
|
```php
|
||||||
|
if (!wp_verify_nonce($_POST['mlf_nonce'], 'mlf_download_font')) {
|
||||||
|
wp_die('Security check failed');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Nonce Names
|
||||||
|
|
||||||
|
Use consistent, descriptive nonce action names:
|
||||||
|
|
||||||
|
| Action | Nonce Name |
|
||||||
|
|--------|------------|
|
||||||
|
| Download font | `mlf_download_font` |
|
||||||
|
| Delete font | `mlf_delete_font` |
|
||||||
|
| Update settings | `mlf_update_settings` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Input Validation
|
||||||
|
|
||||||
|
### Font Name Validation
|
||||||
|
|
||||||
|
```php
|
||||||
|
$font_name = isset($_POST['font_name']) ? sanitize_text_field($_POST['font_name']) : '';
|
||||||
|
|
||||||
|
// Strict allowlist pattern - alphanumeric, spaces, hyphens only
|
||||||
|
if (!preg_match('/^[a-zA-Z0-9\s\-]+$/', $font_name)) {
|
||||||
|
wp_send_json_error(['message' => 'Invalid font name: only letters, numbers, spaces, and hyphens allowed']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Length limit
|
||||||
|
if (strlen($font_name) > 100) {
|
||||||
|
wp_send_json_error(['message' => 'Font name too long']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not empty
|
||||||
|
if (empty($font_name)) {
|
||||||
|
wp_send_json_error(['message' => 'Font name required']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Weight Validation
|
||||||
|
|
||||||
|
```php
|
||||||
|
$weights = isset($_POST['weights']) ? (array) $_POST['weights'] : [];
|
||||||
|
|
||||||
|
// Convert to integers
|
||||||
|
$weights = array_map('absint', $weights);
|
||||||
|
|
||||||
|
// Strict allowlist
|
||||||
|
$allowed_weights = [100, 200, 300, 400, 500, 600, 700, 800, 900];
|
||||||
|
$weights = array_intersect($weights, $allowed_weights);
|
||||||
|
|
||||||
|
// Must have at least one
|
||||||
|
if (empty($weights)) {
|
||||||
|
wp_send_json_error(['message' => 'At least one weight required']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Style Validation
|
||||||
|
|
||||||
|
```php
|
||||||
|
$styles = isset($_POST['styles']) ? (array) $_POST['styles'] : [];
|
||||||
|
|
||||||
|
// Strict allowlist - only these two values ever
|
||||||
|
$allowed_styles = ['normal', 'italic'];
|
||||||
|
$styles = array_filter($styles, function($style) use ($allowed_styles) {
|
||||||
|
return in_array($style, $allowed_styles, true);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Must have at least one
|
||||||
|
if (empty($styles)) {
|
||||||
|
wp_send_json_error(['message' => 'At least one style required']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Font Family ID Validation (for delete)
|
||||||
|
|
||||||
|
```php
|
||||||
|
$font_id = isset($_POST['font_id']) ? absint($_POST['font_id']) : 0;
|
||||||
|
|
||||||
|
if ($font_id < 1) {
|
||||||
|
wp_send_json_error(['message' => 'Invalid font ID']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify it exists and is a font family
|
||||||
|
$font = get_post($font_id);
|
||||||
|
if (!$font || $font->post_type !== 'wp_font_family') {
|
||||||
|
wp_send_json_error(['message' => 'Font not found']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify it's one we imported (not a theme font)
|
||||||
|
if (get_post_meta($font_id, '_mlf_imported', true) !== '1') {
|
||||||
|
wp_send_json_error(['message' => 'Cannot delete theme fonts']);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Operation Security
|
||||||
|
|
||||||
|
### Path Traversal Prevention
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Validate that a path is within the WordPress fonts directory.
|
||||||
|
* Prevents path traversal attacks.
|
||||||
|
*
|
||||||
|
* @param string $path Full path to validate
|
||||||
|
* @return bool True if path is safe, false otherwise
|
||||||
|
*/
|
||||||
|
function mlf_validate_font_path($path) {
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
$fonts_path = wp_normalize_path(trailingslashit($font_dir['path']));
|
||||||
|
|
||||||
|
// Resolve to real path (handles ../ etc)
|
||||||
|
$real_path = realpath($path);
|
||||||
|
|
||||||
|
// If realpath fails, file doesn't exist yet - validate the directory
|
||||||
|
if ($real_path === false) {
|
||||||
|
$dir = dirname($path);
|
||||||
|
$real_dir = realpath($dir);
|
||||||
|
if ($real_dir === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$real_path = wp_normalize_path($real_dir . '/' . basename($path));
|
||||||
|
} else {
|
||||||
|
$real_path = wp_normalize_path($real_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be within fonts directory
|
||||||
|
return strpos($real_path, $fonts_path) === 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Filename Sanitization
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Sanitize and validate a font filename.
|
||||||
|
*
|
||||||
|
* @param string $filename The filename to validate
|
||||||
|
* @return string|false Sanitized filename or false if invalid
|
||||||
|
*/
|
||||||
|
function mlf_sanitize_font_filename($filename) {
|
||||||
|
// WordPress sanitization first
|
||||||
|
$filename = sanitize_file_name($filename);
|
||||||
|
|
||||||
|
// Must have .woff2 extension
|
||||||
|
if (pathinfo($filename, PATHINFO_EXTENSION) !== 'woff2') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No path components
|
||||||
|
if ($filename !== basename($filename)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reasonable length
|
||||||
|
if (strlen($filename) > 200) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $filename;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Safe File Writing
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Safely write a font file to the fonts directory.
|
||||||
|
*
|
||||||
|
* @param string $filename Sanitized filename
|
||||||
|
* @param string $content File content
|
||||||
|
* @return string|WP_Error File path on success, WP_Error on failure
|
||||||
|
*/
|
||||||
|
function mlf_write_font_file($filename, $content) {
|
||||||
|
// Validate filename
|
||||||
|
$safe_filename = mlf_sanitize_font_filename($filename);
|
||||||
|
if ($safe_filename === false) {
|
||||||
|
return new WP_Error('invalid_filename', 'Invalid filename');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get fonts directory
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
$destination = trailingslashit($font_dir['path']) . $safe_filename;
|
||||||
|
|
||||||
|
// Validate path
|
||||||
|
if (!mlf_validate_font_path($destination)) {
|
||||||
|
return new WP_Error('invalid_path', 'Invalid file path');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure directory exists
|
||||||
|
if (!wp_mkdir_p($font_dir['path'])) {
|
||||||
|
return new WP_Error('mkdir_failed', 'Could not create fonts directory');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write file
|
||||||
|
global $wp_filesystem;
|
||||||
|
if (empty($wp_filesystem)) {
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||||
|
WP_Filesystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$wp_filesystem->put_contents($destination, $content, FS_CHMOD_FILE)) {
|
||||||
|
return new WP_Error('write_failed', 'Could not write font file');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $destination;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Safe File Deletion
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Safely delete a font file.
|
||||||
|
*
|
||||||
|
* @param string $path Full path to the file
|
||||||
|
* @return bool True on success, false on failure
|
||||||
|
*/
|
||||||
|
function mlf_delete_font_file($path) {
|
||||||
|
// Validate path is within fonts directory
|
||||||
|
if (!mlf_validate_font_path($path)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Must be a .woff2 file
|
||||||
|
if (pathinfo($path, PATHINFO_EXTENSION) !== 'woff2') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// File must exist
|
||||||
|
if (!file_exists($path)) {
|
||||||
|
return true; // Already gone, that's fine
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_delete_file($path);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## HTTP Request Security
|
||||||
|
|
||||||
|
### Outbound Requests (Google Fonts)
|
||||||
|
|
||||||
|
```php
|
||||||
|
$response = wp_remote_get($url, [
|
||||||
|
'timeout' => 15,
|
||||||
|
'sslverify' => true, // Always verify SSL
|
||||||
|
'user-agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
|
||||||
|
]);
|
||||||
|
|
||||||
|
// Check for errors
|
||||||
|
if (is_wp_error($response)) {
|
||||||
|
// Log error, return gracefully
|
||||||
|
error_log('MLF: Google Fonts request failed - ' . $response->get_error_message());
|
||||||
|
return new WP_Error('request_failed', 'Could not connect to Google Fonts');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check HTTP status
|
||||||
|
$status = wp_remote_retrieve_response_code($response);
|
||||||
|
if ($status !== 200) {
|
||||||
|
return new WP_Error('http_error', 'Google Fonts returned status ' . $status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get body
|
||||||
|
$body = wp_remote_retrieve_body($response);
|
||||||
|
if (empty($body)) {
|
||||||
|
return new WP_Error('empty_response', 'Empty response from Google Fonts');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### URL Validation (Google Fonts only)
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Validate that a URL is a legitimate Google Fonts URL.
|
||||||
|
*
|
||||||
|
* @param string $url URL to validate
|
||||||
|
* @return bool True if valid Google Fonts URL
|
||||||
|
*/
|
||||||
|
function mlf_is_valid_google_fonts_url($url) {
|
||||||
|
$parsed = wp_parse_url($url);
|
||||||
|
|
||||||
|
if (!$parsed || !isset($parsed['host'])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow Google Fonts domains
|
||||||
|
$allowed_hosts = [
|
||||||
|
'fonts.googleapis.com',
|
||||||
|
'fonts.gstatic.com',
|
||||||
|
];
|
||||||
|
|
||||||
|
return in_array($parsed['host'], $allowed_hosts, true);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## AJAX Handler Complete Template
|
||||||
|
|
||||||
|
```php
|
||||||
|
<?php
|
||||||
|
if (!defined('ABSPATH')) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MLF_Ajax_Handler {
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
add_action('wp_ajax_mlf_download_font', [$this, 'handle_download']);
|
||||||
|
add_action('wp_ajax_mlf_delete_font', [$this, 'handle_delete']);
|
||||||
|
// NEVER add wp_ajax_nopriv_ - admin only functionality
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle font download AJAX request.
|
||||||
|
*/
|
||||||
|
public function handle_download() {
|
||||||
|
// 1. NONCE CHECK
|
||||||
|
if (!check_ajax_referer('mlf_download_font', 'nonce', false)) {
|
||||||
|
wp_send_json_error(['message' => 'Security check failed'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. CAPABILITY CHECK
|
||||||
|
if (!current_user_can('edit_theme_options')) {
|
||||||
|
wp_send_json_error(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. INPUT VALIDATION
|
||||||
|
$font_name = isset($_POST['font_name']) ? sanitize_text_field($_POST['font_name']) : '';
|
||||||
|
if (empty($font_name) || !preg_match('/^[a-zA-Z0-9\s\-]+$/', $font_name) || strlen($font_name) > 100) {
|
||||||
|
wp_send_json_error(['message' => 'Invalid font name']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$weights = isset($_POST['weights']) ? array_map('absint', (array) $_POST['weights']) : [];
|
||||||
|
$weights = array_intersect($weights, [100, 200, 300, 400, 500, 600, 700, 800, 900]);
|
||||||
|
if (empty($weights)) {
|
||||||
|
wp_send_json_error(['message' => 'At least one weight required']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$styles = isset($_POST['styles']) ? (array) $_POST['styles'] : [];
|
||||||
|
$styles = array_intersect($styles, ['normal', 'italic']);
|
||||||
|
if (empty($styles)) {
|
||||||
|
wp_send_json_error(['message' => 'At least one style required']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. PROCESS REQUEST
|
||||||
|
try {
|
||||||
|
$downloader = new MLF_Font_Downloader();
|
||||||
|
$result = $downloader->download($font_name, $weights, $styles);
|
||||||
|
|
||||||
|
if (is_wp_error($result)) {
|
||||||
|
wp_send_json_error(['message' => $result->get_error_message()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success([
|
||||||
|
'message' => sprintf('Successfully installed %s', esc_html($font_name)),
|
||||||
|
'font_id' => $result,
|
||||||
|
]);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log('MLF Download Error: ' . $e->getMessage());
|
||||||
|
wp_send_json_error(['message' => 'An unexpected error occurred']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle font deletion AJAX request.
|
||||||
|
*/
|
||||||
|
public function handle_delete() {
|
||||||
|
// 1. NONCE CHECK
|
||||||
|
if (!check_ajax_referer('mlf_delete_font', 'nonce', false)) {
|
||||||
|
wp_send_json_error(['message' => 'Security check failed'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. CAPABILITY CHECK
|
||||||
|
if (!current_user_can('edit_theme_options')) {
|
||||||
|
wp_send_json_error(['message' => 'Unauthorized'], 403);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. INPUT VALIDATION
|
||||||
|
$font_id = isset($_POST['font_id']) ? absint($_POST['font_id']) : 0;
|
||||||
|
if ($font_id < 1) {
|
||||||
|
wp_send_json_error(['message' => 'Invalid font ID']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify font exists and is ours
|
||||||
|
$font = get_post($font_id);
|
||||||
|
if (!$font || $font->post_type !== 'wp_font_family') {
|
||||||
|
wp_send_json_error(['message' => 'Font not found']);
|
||||||
|
}
|
||||||
|
if (get_post_meta($font_id, '_mlf_imported', true) !== '1') {
|
||||||
|
wp_send_json_error(['message' => 'Cannot delete theme fonts']);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. PROCESS REQUEST
|
||||||
|
try {
|
||||||
|
$registry = new MLF_Font_Registry();
|
||||||
|
$result = $registry->delete_font($font_id);
|
||||||
|
|
||||||
|
if (is_wp_error($result)) {
|
||||||
|
wp_send_json_error(['message' => $result->get_error_message()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success(['message' => 'Font deleted successfully']);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
error_log('MLF Delete Error: ' . $e->getMessage());
|
||||||
|
wp_send_json_error(['message' => 'An unexpected error occurred']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Security Checklist
|
||||||
|
|
||||||
|
Before committing any code:
|
||||||
|
|
||||||
|
- [ ] ABSPATH check at top of every PHP file
|
||||||
|
- [ ] index.php exists in every directory
|
||||||
|
- [ ] All AJAX handlers verify nonce first
|
||||||
|
- [ ] All AJAX handlers check capability second
|
||||||
|
- [ ] All user input sanitized with appropriate function
|
||||||
|
- [ ] All user input validated against allowlists where applicable
|
||||||
|
- [ ] All output escaped with appropriate function
|
||||||
|
- [ ] File paths validated to prevent traversal
|
||||||
|
- [ ] No direct SQL queries (use WordPress APIs)
|
||||||
|
- [ ] No `unserialize()` on user input
|
||||||
|
- [ ] No `eval()` or similar dynamic execution
|
||||||
|
- [ ] External URLs validated before use
|
||||||
|
- [ ] Error messages don't expose sensitive info
|
||||||
560
native/wordpress/maple-icons-wp/WORDPRESS_COMPATIBILITY.md
Normal file
560
native/wordpress/maple-icons-wp/WORDPRESS_COMPATIBILITY.md
Normal file
|
|
@ -0,0 +1,560 @@
|
||||||
|
# WORDPRESS_COMPATIBILITY.md — WordPress & Plugin Compatibility
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document covers compatibility requirements for WordPress core systems and popular plugins. Reference this when building the font registry class and integration points.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WordPress Version Requirements
|
||||||
|
|
||||||
|
**Minimum: WordPress 6.5**
|
||||||
|
|
||||||
|
WordPress 6.5 introduced the Font Library API which this plugin depends on. Earlier versions will not work.
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Check on activation
|
||||||
|
register_activation_hook(__FILE__, function() {
|
||||||
|
if (version_compare(get_bloginfo('version'), '6.5', '<')) {
|
||||||
|
deactivate_plugins(plugin_basename(__FILE__));
|
||||||
|
wp_die(
|
||||||
|
'Maple Local Fonts requires WordPress 6.5 or higher for Font Library support.',
|
||||||
|
'Plugin Activation Error',
|
||||||
|
['back_link' => true]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Also check on admin init (in case WP was downgraded)
|
||||||
|
add_action('admin_init', function() {
|
||||||
|
if (version_compare(get_bloginfo('version'), '6.5', '<')) {
|
||||||
|
deactivate_plugins(plugin_basename(__FILE__));
|
||||||
|
add_action('admin_notices', function() {
|
||||||
|
echo '<div class="error"><p>Maple Local Fonts has been deactivated. It requires WordPress 6.5 or higher.</p></div>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WordPress Font Library API
|
||||||
|
|
||||||
|
### How It Works
|
||||||
|
|
||||||
|
WordPress 6.5+ stores fonts using custom post types:
|
||||||
|
|
||||||
|
| Post Type | Purpose |
|
||||||
|
|-----------|---------|
|
||||||
|
| `wp_font_family` | Font family (e.g., "Open Sans") |
|
||||||
|
| `wp_font_face` | Individual weight/style variant (child of family) |
|
||||||
|
|
||||||
|
Fonts are stored in `wp-content/fonts/` by default.
|
||||||
|
|
||||||
|
### Getting the Fonts Directory
|
||||||
|
|
||||||
|
```php
|
||||||
|
// ALWAYS use this function, never hardcode paths
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
|
||||||
|
// Returns:
|
||||||
|
[
|
||||||
|
'path' => '/var/www/html/wp-content/fonts',
|
||||||
|
'url' => 'https://example.com/wp-content/fonts',
|
||||||
|
'subdir' => '',
|
||||||
|
'basedir' => '/var/www/html/wp-content/fonts',
|
||||||
|
'baseurl' => 'https://example.com/wp-content/fonts',
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Registering a Font Family
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Register a font family with WordPress Font Library.
|
||||||
|
*
|
||||||
|
* @param string $font_name Display name (e.g., "Open Sans")
|
||||||
|
* @param string $font_slug Slug (e.g., "open-sans")
|
||||||
|
* @param array $files Array of downloaded file data
|
||||||
|
* @return int|WP_Error Font family post ID or error
|
||||||
|
*/
|
||||||
|
function mlf_register_font_family($font_name, $font_slug, $files) {
|
||||||
|
// Check if font already exists
|
||||||
|
$existing = get_posts([
|
||||||
|
'post_type' => 'wp_font_family',
|
||||||
|
'name' => $font_slug,
|
||||||
|
'posts_per_page' => 1,
|
||||||
|
'post_status' => 'publish',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (!empty($existing)) {
|
||||||
|
return new WP_Error('font_exists', 'Font family already installed');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build font family settings
|
||||||
|
$font_family_settings = [
|
||||||
|
'name' => $font_name,
|
||||||
|
'slug' => $font_slug,
|
||||||
|
'fontFamily' => sprintf('"%s", sans-serif', $font_name),
|
||||||
|
'fontFace' => [],
|
||||||
|
];
|
||||||
|
|
||||||
|
// Add each font face
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
$relative_path = str_replace($font_dir['path'], '', $file['path']);
|
||||||
|
|
||||||
|
$font_family_settings['fontFace'][] = [
|
||||||
|
'fontFamily' => $font_name,
|
||||||
|
'fontWeight' => $file['weight'],
|
||||||
|
'fontStyle' => $file['style'],
|
||||||
|
'src' => 'file:.' . $font_dir['basedir'] . $relative_path,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create font family post
|
||||||
|
$family_id = wp_insert_post([
|
||||||
|
'post_type' => 'wp_font_family',
|
||||||
|
'post_title' => $font_name,
|
||||||
|
'post_name' => $font_slug,
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_content' => wp_json_encode($font_family_settings),
|
||||||
|
]);
|
||||||
|
|
||||||
|
if (is_wp_error($family_id)) {
|
||||||
|
return $family_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as imported by our plugin (for identification)
|
||||||
|
update_post_meta($family_id, '_mlf_imported', '1');
|
||||||
|
update_post_meta($family_id, '_mlf_import_date', current_time('mysql'));
|
||||||
|
|
||||||
|
// Create font face posts (children)
|
||||||
|
foreach ($files as $file) {
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
|
||||||
|
$face_settings = [
|
||||||
|
'fontFamily' => $font_name,
|
||||||
|
'fontWeight' => $file['weight'],
|
||||||
|
'fontStyle' => $file['style'],
|
||||||
|
'src' => 'file:.' . $font_dir['baseurl'] . '/' . basename($file['path']),
|
||||||
|
];
|
||||||
|
|
||||||
|
wp_insert_post([
|
||||||
|
'post_type' => 'wp_font_face',
|
||||||
|
'post_parent' => $family_id,
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'post_content' => wp_json_encode($face_settings),
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear font caches
|
||||||
|
delete_transient('wp_font_library_fonts');
|
||||||
|
|
||||||
|
return $family_id;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Deleting a Font Family
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Delete a font family and its files.
|
||||||
|
*
|
||||||
|
* @param int $family_id Font family post ID
|
||||||
|
* @return bool|WP_Error True on success, error on failure
|
||||||
|
*/
|
||||||
|
function mlf_delete_font_family($family_id) {
|
||||||
|
$family = get_post($family_id);
|
||||||
|
|
||||||
|
if (!$family || $family->post_type !== 'wp_font_family') {
|
||||||
|
return new WP_Error('not_found', 'Font family not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify it's one we imported
|
||||||
|
if (get_post_meta($family_id, '_mlf_imported', true) !== '1') {
|
||||||
|
return new WP_Error('not_ours', 'Cannot delete fonts not imported by this plugin');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get font faces
|
||||||
|
$faces = get_children([
|
||||||
|
'post_parent' => $family_id,
|
||||||
|
'post_type' => 'wp_font_face',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$font_dir = wp_get_font_dir();
|
||||||
|
|
||||||
|
// Delete font face files and posts
|
||||||
|
foreach ($faces as $face) {
|
||||||
|
$settings = json_decode($face->post_content, true);
|
||||||
|
|
||||||
|
if (isset($settings['src'])) {
|
||||||
|
// Convert file:. URL to path
|
||||||
|
$src = $settings['src'];
|
||||||
|
$src = str_replace('file:.', '', $src);
|
||||||
|
|
||||||
|
// Handle both URL and path formats
|
||||||
|
if (strpos($src, $font_dir['baseurl']) !== false) {
|
||||||
|
$file_path = str_replace($font_dir['baseurl'], $font_dir['path'], $src);
|
||||||
|
} else {
|
||||||
|
$file_path = $font_dir['path'] . '/' . basename($src);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate path before deletion
|
||||||
|
if (mlf_validate_font_path($file_path) && file_exists($file_path)) {
|
||||||
|
wp_delete_file($file_path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_delete_post($face->ID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete family post
|
||||||
|
wp_delete_post($family_id, true);
|
||||||
|
|
||||||
|
// Clear caches
|
||||||
|
delete_transient('wp_font_library_fonts');
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Listing Installed Fonts
|
||||||
|
|
||||||
|
```php
|
||||||
|
/**
|
||||||
|
* Get all fonts imported by this plugin.
|
||||||
|
*
|
||||||
|
* @return array Array of font data
|
||||||
|
*/
|
||||||
|
function mlf_get_imported_fonts() {
|
||||||
|
$fonts = get_posts([
|
||||||
|
'post_type' => 'wp_font_family',
|
||||||
|
'posts_per_page' => 100,
|
||||||
|
'post_status' => 'publish',
|
||||||
|
'meta_key' => '_mlf_imported',
|
||||||
|
'meta_value' => '1',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($fonts as $font) {
|
||||||
|
$settings = json_decode($font->post_content, true);
|
||||||
|
|
||||||
|
// Get variants
|
||||||
|
$faces = get_children([
|
||||||
|
'post_parent' => $font->ID,
|
||||||
|
'post_type' => 'wp_font_face',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$variants = [];
|
||||||
|
foreach ($faces as $face) {
|
||||||
|
$face_settings = json_decode($face->post_content, true);
|
||||||
|
$variants[] = [
|
||||||
|
'weight' => $face_settings['fontWeight'] ?? '400',
|
||||||
|
'style' => $face_settings['fontStyle'] ?? 'normal',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$result[] = [
|
||||||
|
'id' => $font->ID,
|
||||||
|
'name' => $settings['name'] ?? $font->post_title,
|
||||||
|
'slug' => $settings['slug'] ?? $font->post_name,
|
||||||
|
'variants' => $variants,
|
||||||
|
'import_date' => get_post_meta($font->ID, '_mlf_import_date', true),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Gutenberg FSE Integration
|
||||||
|
|
||||||
|
### How Fonts Appear in the Editor
|
||||||
|
|
||||||
|
Once registered via the Font Library API, fonts automatically appear in:
|
||||||
|
|
||||||
|
1. **Global Styles** → Typography → Font dropdown
|
||||||
|
2. **Block settings** → Typography → Font dropdown (when per-block typography is enabled)
|
||||||
|
|
||||||
|
No additional integration code is needed — WordPress handles this automatically.
|
||||||
|
|
||||||
|
### Theme.json Compatibility
|
||||||
|
|
||||||
|
**DO NOT:**
|
||||||
|
- Directly modify theme.json
|
||||||
|
- Filter `wp_theme_json_data_theme` to inject fonts (let Font Library handle it)
|
||||||
|
- Override global styles CSS directly
|
||||||
|
|
||||||
|
**DO:**
|
||||||
|
- Use the Font Library API (post types)
|
||||||
|
- Let WordPress generate CSS custom properties
|
||||||
|
- Trust the system
|
||||||
|
|
||||||
|
### CSS Custom Properties
|
||||||
|
|
||||||
|
When a font is applied in Global Styles, WordPress generates:
|
||||||
|
|
||||||
|
```css
|
||||||
|
body {
|
||||||
|
--wp--preset--font-family--open-sans: "Open Sans", sans-serif;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
And applies it:
|
||||||
|
|
||||||
|
```css
|
||||||
|
body {
|
||||||
|
font-family: var(--wp--preset--font-family--open-sans);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Our plugin doesn't need to touch this — it's automatic.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WooCommerce Compatibility
|
||||||
|
|
||||||
|
### HPOS (High-Performance Order Storage)
|
||||||
|
|
||||||
|
WooCommerce's HPOS moves order data from post meta to custom tables. We must declare compatibility.
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Declare HPOS compatibility
|
||||||
|
add_action('before_woocommerce_init', function() {
|
||||||
|
if (class_exists(\Automattic\WooCommerce\Utilities\FeaturesUtil::class)) {
|
||||||
|
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
|
||||||
|
'custom_order_tables',
|
||||||
|
__FILE__,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Why We're Compatible
|
||||||
|
|
||||||
|
Our plugin:
|
||||||
|
- Does NOT interact with orders at all
|
||||||
|
- Does NOT query wp_posts for order data
|
||||||
|
- Does NOT use wp_postmeta for order data
|
||||||
|
- Only uses wp_font_family and wp_font_face post types
|
||||||
|
|
||||||
|
We're inherently compatible because we don't touch WooCommerce data.
|
||||||
|
|
||||||
|
### Frontend Considerations
|
||||||
|
|
||||||
|
**DO NOT:**
|
||||||
|
- Override `.woocommerce` class styles
|
||||||
|
- Override `.wc-block-*` styles
|
||||||
|
- Target cart/checkout elements specifically
|
||||||
|
|
||||||
|
**DO:**
|
||||||
|
- Let WooCommerce elements inherit from body/heading fonts
|
||||||
|
- Let global styles cascade naturally
|
||||||
|
|
||||||
|
WooCommerce product titles, descriptions, and other text will naturally inherit the fonts set via Global Styles. No special handling needed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wordfence Compatibility
|
||||||
|
|
||||||
|
### Potential Concerns
|
||||||
|
|
||||||
|
1. **Outbound requests** to Google Fonts during import
|
||||||
|
2. **AJAX endpoints** for admin actions
|
||||||
|
3. **File operations** in wp-content
|
||||||
|
|
||||||
|
### Why We're Compatible
|
||||||
|
|
||||||
|
**Outbound Requests:**
|
||||||
|
- Only occur during admin import (user-initiated action)
|
||||||
|
- Target well-known domains (fonts.googleapis.com, fonts.gstatic.com)
|
||||||
|
- Use standard `wp_remote_get()` which Wordfence allows
|
||||||
|
- No runtime external requests on frontend
|
||||||
|
|
||||||
|
**AJAX Endpoints:**
|
||||||
|
- Use standard `admin-ajax.php` (not custom endpoints)
|
||||||
|
- Include proper nonces
|
||||||
|
- Follow WordPress patterns that Wordfence expects
|
||||||
|
|
||||||
|
**File Operations:**
|
||||||
|
- Write only to `wp-content/fonts/` (WordPress default directory)
|
||||||
|
- Use WordPress Filesystem API
|
||||||
|
- Don't create executable files
|
||||||
|
|
||||||
|
### Testing with Wordfence
|
||||||
|
|
||||||
|
Test these scenarios with Wordfence active:
|
||||||
|
|
||||||
|
- [ ] Learning Mode: Import should succeed
|
||||||
|
- [ ] Enabled Mode: Import should succeed
|
||||||
|
- [ ] Rate Limiting: Admin AJAX not blocked
|
||||||
|
- [ ] Firewall: No false positives on font download
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## LearnDash Compatibility
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
LearnDash is a WordPress LMS that uses:
|
||||||
|
- Custom post types (courses, lessons, topics, quizzes)
|
||||||
|
- Custom templates
|
||||||
|
- Focus Mode (distraction-free learning)
|
||||||
|
|
||||||
|
### Why We're Compatible
|
||||||
|
|
||||||
|
Our plugin:
|
||||||
|
- Doesn't touch LearnDash post types
|
||||||
|
- Doesn't modify LearnDash templates
|
||||||
|
- Doesn't inject CSS on frontend
|
||||||
|
- Lets Global Styles cascade to LearnDash content
|
||||||
|
|
||||||
|
LearnDash course content, lesson text, and quiz questions will inherit the fonts set in Global Styles automatically.
|
||||||
|
|
||||||
|
### Focus Mode Consideration
|
||||||
|
|
||||||
|
LearnDash Focus Mode uses its own template. Fonts set via Global Styles will apply because:
|
||||||
|
- Focus Mode still loads theme.json styles
|
||||||
|
- CSS custom properties cascade to all content
|
||||||
|
- No special handling needed
|
||||||
|
|
||||||
|
**DO NOT:**
|
||||||
|
- Target `.learndash-*` classes specifically
|
||||||
|
- Override Focus Mode styles
|
||||||
|
- Inject custom CSS for LearnDash
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## WPForms Compatibility
|
||||||
|
|
||||||
|
### Overview
|
||||||
|
|
||||||
|
WPForms renders forms via shortcodes and blocks. Form styling is handled by WPForms.
|
||||||
|
|
||||||
|
### Why We're Compatible
|
||||||
|
|
||||||
|
- Form labels and text inherit from body font
|
||||||
|
- We don't override `.wpforms-*` classes
|
||||||
|
- No JavaScript conflicts (we have no frontend JS)
|
||||||
|
|
||||||
|
### Consideration
|
||||||
|
|
||||||
|
If a user wants form text in a different font, they should use WPForms' built-in styling options or custom CSS — not expect our plugin to handle it.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## General Best Practices
|
||||||
|
|
||||||
|
### What We Hook Into
|
||||||
|
|
||||||
|
```php
|
||||||
|
// Admin menu
|
||||||
|
add_action('admin_menu', [$this, 'register_menu']);
|
||||||
|
|
||||||
|
// Admin assets (only on our page)
|
||||||
|
add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
|
||||||
|
|
||||||
|
// AJAX handlers
|
||||||
|
add_action('wp_ajax_mlf_download_font', [$this, 'handle_download']);
|
||||||
|
add_action('wp_ajax_mlf_delete_font', [$this, 'handle_delete']);
|
||||||
|
|
||||||
|
// WooCommerce HPOS compatibility
|
||||||
|
add_action('before_woocommerce_init', [$this, 'declare_hpos_compatibility']);
|
||||||
|
```
|
||||||
|
|
||||||
|
### What We DON'T Hook Into
|
||||||
|
|
||||||
|
```php
|
||||||
|
// NO frontend hooks
|
||||||
|
// add_action('wp_enqueue_scripts', ...); // DON'T DO THIS
|
||||||
|
// add_action('wp_head', ...); // DON'T DO THIS
|
||||||
|
// add_action('wp_footer', ...); // DON'T DO THIS
|
||||||
|
|
||||||
|
// NO theme modification hooks
|
||||||
|
// add_filter('wp_theme_json_data_theme', ...); // Let Font Library handle it
|
||||||
|
|
||||||
|
// NO WooCommerce hooks
|
||||||
|
// add_action('woocommerce_*', ...); // DON'T DO THIS
|
||||||
|
|
||||||
|
// NO content filters
|
||||||
|
// add_filter('the_content', ...); // DON'T DO THIS
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conflict Debugging
|
||||||
|
|
||||||
|
If a user reports a conflict, check:
|
||||||
|
|
||||||
|
### 1. Plugin Load Order
|
||||||
|
|
||||||
|
Our plugin should load with default priority. Check if another plugin is:
|
||||||
|
- Modifying the Font Library
|
||||||
|
- Overriding font CSS
|
||||||
|
- Filtering theme.json
|
||||||
|
|
||||||
|
### 2. CSS Specificity
|
||||||
|
|
||||||
|
If fonts aren't applying:
|
||||||
|
- Check browser DevTools for CSS cascade
|
||||||
|
- Look for more specific selectors overriding global styles
|
||||||
|
- Check for `!important` declarations
|
||||||
|
|
||||||
|
### 3. Cache Issues
|
||||||
|
|
||||||
|
Font changes not appearing:
|
||||||
|
- Clear browser cache
|
||||||
|
- Clear any caching plugins (WP Rocket, W3TC, etc.)
|
||||||
|
- Clear CDN cache if applicable
|
||||||
|
- WordPress transients: `delete_transient('wp_font_library_fonts')`
|
||||||
|
|
||||||
|
### 4. JavaScript Errors
|
||||||
|
|
||||||
|
If admin page isn't working:
|
||||||
|
- Check browser console for JS errors
|
||||||
|
- Look for conflicts with other admin scripts
|
||||||
|
- Verify jQuery isn't being dequeued
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Compatibility Checklist
|
||||||
|
|
||||||
|
Before releasing:
|
||||||
|
|
||||||
|
### WordPress Core
|
||||||
|
- [ ] Works on WordPress 6.5
|
||||||
|
- [ ] Works on WordPress 6.6+
|
||||||
|
- [ ] Font Library API integration works
|
||||||
|
- [ ] Fonts appear in Global Styles
|
||||||
|
- [ ] Fonts apply correctly on frontend
|
||||||
|
|
||||||
|
### WooCommerce
|
||||||
|
- [ ] HPOS compatibility declared
|
||||||
|
- [ ] No errors in WooCommerce status page
|
||||||
|
- [ ] Product pages render correctly with custom fonts
|
||||||
|
- [ ] Cart/Checkout not affected
|
||||||
|
|
||||||
|
### Wordfence
|
||||||
|
- [ ] Import works with firewall enabled
|
||||||
|
- [ ] No blocked requests
|
||||||
|
- [ ] No false positive security alerts
|
||||||
|
|
||||||
|
### LearnDash
|
||||||
|
- [ ] Course content inherits fonts
|
||||||
|
- [ ] Focus Mode renders correctly
|
||||||
|
- [ ] No JavaScript conflicts
|
||||||
|
|
||||||
|
### WPForms
|
||||||
|
- [ ] Forms render correctly
|
||||||
|
- [ ] No styling conflicts
|
||||||
|
|
||||||
|
### Other
|
||||||
|
- [ ] No PHP errors in debug.log
|
||||||
|
- [ ] No JavaScript errors in console
|
||||||
|
- [ ] Admin page loads correctly
|
||||||
|
- [ ] No memory issues during import
|
||||||
294
native/wordpress/maple-icons-wp/assets/admin.css
Normal file
294
native/wordpress/maple-icons-wp/assets/admin.css
Normal file
|
|
@ -0,0 +1,294 @@
|
||||||
|
/**
|
||||||
|
* Maple Icons - Admin Styles
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Admin page wrapper */
|
||||||
|
.mi-admin-wrap {
|
||||||
|
max-width: 1200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-intro {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #c3c4c7;
|
||||||
|
border-left: 4px solid #2271b1;
|
||||||
|
padding: 12px 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-intro p {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Icon sets grid */
|
||||||
|
.mi-sets-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(320px, 1fr));
|
||||||
|
gap: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Individual set card */
|
||||||
|
.mi-set-card {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #c3c4c7;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
position: relative;
|
||||||
|
transition: border-color 0.2s, box-shadow 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-card:hover {
|
||||||
|
border-color: #2271b1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-card.mi-set-active {
|
||||||
|
border-color: #00a32a;
|
||||||
|
box-shadow: 0 0 0 1px #00a32a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-card.mi-set-downloading {
|
||||||
|
opacity: 0.8;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Card header */
|
||||||
|
.mi-set-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-name {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2327;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badges */
|
||||||
|
.mi-badge {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-badge-active {
|
||||||
|
background: #00a32a;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-badge-downloaded {
|
||||||
|
background: #dcdcde;
|
||||||
|
color: #50575e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set metadata */
|
||||||
|
.mi-set-meta {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #50575e;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-count {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #1d2327;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* External link */
|
||||||
|
.mi-set-link {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
font-size: 13px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-link:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Action buttons */
|
||||||
|
.mi-set-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-actions .button {
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-delete-btn {
|
||||||
|
color: #d63638 !important;
|
||||||
|
border-color: #d63638 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-delete-btn:hover {
|
||||||
|
background: #d63638 !important;
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress bar */
|
||||||
|
.mi-set-progress {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-progress-bar {
|
||||||
|
height: 8px;
|
||||||
|
background: #dcdcde;
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-progress-fill {
|
||||||
|
height: 100%;
|
||||||
|
background: #2271b1;
|
||||||
|
border-radius: 4px;
|
||||||
|
width: 0;
|
||||||
|
transition: width 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-progress-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #50575e;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Messages */
|
||||||
|
.mi-set-message {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-radius: 4px;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-message.mi-message-success {
|
||||||
|
background: #edfaef;
|
||||||
|
border: 1px solid #00a32a;
|
||||||
|
color: #00450c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-message.mi-message-error {
|
||||||
|
background: #fcf0f1;
|
||||||
|
border: 1px solid #d63638;
|
||||||
|
color: #8a1f22;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-message.mi-message-info {
|
||||||
|
background: #f0f6fc;
|
||||||
|
border: 1px solid #2271b1;
|
||||||
|
color: #135e96;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Usage section */
|
||||||
|
.mi-admin-usage,
|
||||||
|
.mi-admin-info {
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #c3c4c7;
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 20px;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-usage h2,
|
||||||
|
.mi-admin-info h2 {
|
||||||
|
margin-top: 0;
|
||||||
|
font-size: 16px;
|
||||||
|
border-bottom: 1px solid #c3c4c7;
|
||||||
|
padding-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-usage ol {
|
||||||
|
margin: 16px 0 0;
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-usage li {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-info p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-info p:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-admin-info code {
|
||||||
|
background: #f0f0f1;
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loading spinner */
|
||||||
|
.mi-spinner {
|
||||||
|
display: inline-block;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border: 2px solid #c3c4c7;
|
||||||
|
border-top-color: #2271b1;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: mi-spin 0.8s linear infinite;
|
||||||
|
margin-right: 8px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes mi-spin {
|
||||||
|
to {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Button loading state */
|
||||||
|
.button.mi-loading {
|
||||||
|
position: relative;
|
||||||
|
color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.mi-loading::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin: -7px 0 0 -7px;
|
||||||
|
border: 2px solid currentColor;
|
||||||
|
border-top-color: transparent;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: mi-spin 0.8s linear infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-primary.mi-loading::after {
|
||||||
|
border-color: rgba(255, 255, 255, 0.3);
|
||||||
|
border-top-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive adjustments */
|
||||||
|
@media screen and (max-width: 782px) {
|
||||||
|
.mi-sets-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-actions {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mi-set-actions .button {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
255
native/wordpress/maple-icons-wp/assets/admin.js
Normal file
255
native/wordpress/maple-icons-wp/assets/admin.js
Normal file
|
|
@ -0,0 +1,255 @@
|
||||||
|
/**
|
||||||
|
* Maple Icons - Admin JavaScript
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show message on a card.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
* @param {string} message The message text.
|
||||||
|
* @param {string} type Message type: success, error, info.
|
||||||
|
*/
|
||||||
|
function showMessage($card, message, type) {
|
||||||
|
var $message = $card.find('.mi-set-message');
|
||||||
|
$message
|
||||||
|
.removeClass('mi-message-success mi-message-error mi-message-info')
|
||||||
|
.addClass('mi-message-' + type)
|
||||||
|
.text(message)
|
||||||
|
.show();
|
||||||
|
|
||||||
|
// Auto-hide success messages after 5 seconds.
|
||||||
|
if (type === 'success') {
|
||||||
|
setTimeout(function() {
|
||||||
|
$message.fadeOut();
|
||||||
|
}, 5000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide message on a card.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
*/
|
||||||
|
function hideMessage($card) {
|
||||||
|
$card.find('.mi-set-message').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show progress bar.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
*/
|
||||||
|
function showProgress($card) {
|
||||||
|
$card.find('.mi-set-progress').show();
|
||||||
|
$card.find('.mi-set-actions').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hide progress bar.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
*/
|
||||||
|
function hideProgress($card) {
|
||||||
|
$card.find('.mi-set-progress').hide();
|
||||||
|
$card.find('.mi-set-actions').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update progress bar.
|
||||||
|
*
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
* @param {number} percentage Progress percentage (0-100).
|
||||||
|
* @param {string} text Progress text.
|
||||||
|
*/
|
||||||
|
function updateProgress($card, percentage, text) {
|
||||||
|
$card.find('.mi-progress-fill').css('width', percentage + '%');
|
||||||
|
$card.find('.mi-progress-text').text(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Poll download progress.
|
||||||
|
*
|
||||||
|
* @param {string} slug Icon set slug.
|
||||||
|
* @param {jQuery} $card The card element.
|
||||||
|
*/
|
||||||
|
function pollProgress(slug, $card) {
|
||||||
|
$.ajax({
|
||||||
|
url: miAdmin.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'mi_get_progress',
|
||||||
|
nonce: miAdmin.nonce,
|
||||||
|
slug: slug
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
if (response.success && response.data.downloading) {
|
||||||
|
var percentage = response.data.percentage || 0;
|
||||||
|
var text = response.data.completed + ' / ' + response.data.total + ' icons';
|
||||||
|
updateProgress($card, percentage, text);
|
||||||
|
|
||||||
|
// Continue polling if still downloading.
|
||||||
|
setTimeout(function() {
|
||||||
|
pollProgress(slug, $card);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle download button click.
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.mi-download-btn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var $btn = $(this);
|
||||||
|
var $card = $btn.closest('.mi-set-card');
|
||||||
|
var slug = $btn.data('slug');
|
||||||
|
|
||||||
|
if ($btn.hasClass('mi-loading')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$btn.addClass('mi-loading');
|
||||||
|
$card.addClass('mi-set-downloading');
|
||||||
|
hideMessage($card);
|
||||||
|
showProgress($card);
|
||||||
|
updateProgress($card, 0, miAdmin.strings.downloading);
|
||||||
|
|
||||||
|
// Start polling for progress.
|
||||||
|
setTimeout(function() {
|
||||||
|
pollProgress(slug, $card);
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: miAdmin.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'mi_download_set',
|
||||||
|
nonce: miAdmin.nonce,
|
||||||
|
slug: slug
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
hideProgress($card);
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
$card.removeClass('mi-set-downloading');
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.downloadSuccess, 'success');
|
||||||
|
// Reload page to update UI state.
|
||||||
|
setTimeout(function() {
|
||||||
|
location.reload();
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.downloadError, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
hideProgress($card);
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
$card.removeClass('mi-set-downloading');
|
||||||
|
showMessage($card, miAdmin.strings.downloadError, 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle delete button click.
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.mi-delete-btn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var $btn = $(this);
|
||||||
|
var $card = $btn.closest('.mi-set-card');
|
||||||
|
var slug = $btn.data('slug');
|
||||||
|
|
||||||
|
if ($btn.hasClass('mi-loading')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!confirm(miAdmin.strings.confirmDelete)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$btn.addClass('mi-loading');
|
||||||
|
hideMessage($card);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: miAdmin.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'mi_delete_set',
|
||||||
|
nonce: miAdmin.nonce,
|
||||||
|
slug: slug
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.deleteSuccess, 'success');
|
||||||
|
// Reload page to update UI state.
|
||||||
|
setTimeout(function() {
|
||||||
|
location.reload();
|
||||||
|
}, 1500);
|
||||||
|
} else {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.deleteError, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
showMessage($card, miAdmin.strings.deleteError, 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle activate button click.
|
||||||
|
*/
|
||||||
|
$(document).on('click', '.mi-activate-btn, .mi-deactivate-btn', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var $btn = $(this);
|
||||||
|
var $card = $btn.closest('.mi-set-card');
|
||||||
|
var slug = $btn.data('slug');
|
||||||
|
|
||||||
|
if ($btn.hasClass('mi-loading')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$btn.addClass('mi-loading');
|
||||||
|
hideMessage($card);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
url: miAdmin.ajaxUrl,
|
||||||
|
type: 'POST',
|
||||||
|
data: {
|
||||||
|
action: 'mi_set_active',
|
||||||
|
nonce: miAdmin.nonce,
|
||||||
|
slug: slug
|
||||||
|
},
|
||||||
|
success: function(response) {
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
|
||||||
|
if (response.success) {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.activateSuccess, 'success');
|
||||||
|
// Reload page to update UI state.
|
||||||
|
setTimeout(function() {
|
||||||
|
location.reload();
|
||||||
|
}, 1000);
|
||||||
|
} else {
|
||||||
|
showMessage($card, response.data.message || miAdmin.strings.activateError, 'error');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function() {
|
||||||
|
$btn.removeClass('mi-loading');
|
||||||
|
showMessage($card, miAdmin.strings.activateError, 'error');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
})(jQuery);
|
||||||
5
native/wordpress/maple-icons-wp/assets/index.php
Normal file
5
native/wordpress/maple-icons-wp/assets/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
224
native/wordpress/maple-icons-wp/includes/class-mi-admin-page.php
Normal file
224
native/wordpress/maple-icons-wp/includes/class-mi-admin-page.php
Normal file
|
|
@ -0,0 +1,224 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Admin Page class - Handles the settings page.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MI_Admin_Page
|
||||||
|
*
|
||||||
|
* Handles the plugin settings page in WordPress admin.
|
||||||
|
*/
|
||||||
|
class MI_Admin_Page {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor - Register admin hooks.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
add_action( 'admin_menu', array( $this, 'register_menu' ) );
|
||||||
|
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the admin menu item.
|
||||||
|
*/
|
||||||
|
public function register_menu() {
|
||||||
|
add_options_page(
|
||||||
|
__( 'Maple Icons', 'maple-icons' ),
|
||||||
|
__( 'Maple Icons', 'maple-icons' ),
|
||||||
|
'manage_options',
|
||||||
|
'maple-icons',
|
||||||
|
array( $this, 'render_page' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue admin assets.
|
||||||
|
*
|
||||||
|
* @param string $hook_suffix The current admin page.
|
||||||
|
*/
|
||||||
|
public function enqueue_assets( $hook_suffix ) {
|
||||||
|
if ( 'settings_page_maple-icons' !== $hook_suffix ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_enqueue_style(
|
||||||
|
'mi-admin',
|
||||||
|
MI_PLUGIN_URL . 'assets/admin.css',
|
||||||
|
array(),
|
||||||
|
MI_VERSION
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_enqueue_script(
|
||||||
|
'mi-admin',
|
||||||
|
MI_PLUGIN_URL . 'assets/admin.js',
|
||||||
|
array( 'jquery' ),
|
||||||
|
MI_VERSION,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
|
wp_localize_script(
|
||||||
|
'mi-admin',
|
||||||
|
'miAdmin',
|
||||||
|
array(
|
||||||
|
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||||
|
'nonce' => wp_create_nonce( 'mi_admin_nonce' ),
|
||||||
|
'strings' => array(
|
||||||
|
'downloading' => __( 'Downloading...', 'maple-icons' ),
|
||||||
|
'deleting' => __( 'Deleting...', 'maple-icons' ),
|
||||||
|
'activating' => __( 'Activating...', 'maple-icons' ),
|
||||||
|
'confirmDelete' => __( 'Are you sure you want to delete this icon set?', 'maple-icons' ),
|
||||||
|
'downloadError' => __( 'Download failed. Please try again.', 'maple-icons' ),
|
||||||
|
'deleteError' => __( 'Delete failed. Please try again.', 'maple-icons' ),
|
||||||
|
'activateError' => __( 'Activation failed. Please try again.', 'maple-icons' ),
|
||||||
|
'downloadSuccess'=> __( 'Icon set downloaded successfully!', 'maple-icons' ),
|
||||||
|
'deleteSuccess' => __( 'Icon set deleted successfully!', 'maple-icons' ),
|
||||||
|
'activateSuccess'=> __( 'Icon set activated!', 'maple-icons' ),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render the settings page.
|
||||||
|
*/
|
||||||
|
public function render_page() {
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
$all_sets = MI_Icon_Sets::get_all();
|
||||||
|
$downloaded = $registry->get_downloaded_sets();
|
||||||
|
$active_set = $registry->get_active_set();
|
||||||
|
|
||||||
|
?>
|
||||||
|
<div class="wrap mi-admin-wrap">
|
||||||
|
<h1><?php esc_html_e( 'Maple Icons', 'maple-icons' ); ?></h1>
|
||||||
|
|
||||||
|
<div class="mi-admin-intro">
|
||||||
|
<p><?php esc_html_e( 'Download icon sets from CDN and use them in the Gutenberg block editor. Only one icon set can be active at a time.', 'maple-icons' ); ?></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-icon-sets">
|
||||||
|
<h2><?php esc_html_e( 'Available Icon Sets', 'maple-icons' ); ?></h2>
|
||||||
|
|
||||||
|
<div class="mi-sets-grid">
|
||||||
|
<?php foreach ( $all_sets as $slug => $set ) : ?>
|
||||||
|
<?php
|
||||||
|
$is_downloaded = isset( $downloaded[ $slug ] );
|
||||||
|
$is_active = $active_set === $slug;
|
||||||
|
$icon_count = $is_downloaded ? $downloaded[ $slug ]['icon_count'] : 0;
|
||||||
|
$download_date = $is_downloaded ? $downloaded[ $slug ]['downloaded_at'] : '';
|
||||||
|
?>
|
||||||
|
<div class="mi-set-card <?php echo $is_active ? 'mi-set-active' : ''; ?> <?php echo $is_downloaded ? 'mi-set-downloaded' : ''; ?>" data-slug="<?php echo esc_attr( $slug ); ?>">
|
||||||
|
<div class="mi-set-header">
|
||||||
|
<h3 class="mi-set-name"><?php echo esc_html( $set['name'] ); ?></h3>
|
||||||
|
<?php if ( $is_active ) : ?>
|
||||||
|
<span class="mi-badge mi-badge-active"><?php esc_html_e( 'Active', 'maple-icons' ); ?></span>
|
||||||
|
<?php elseif ( $is_downloaded ) : ?>
|
||||||
|
<span class="mi-badge mi-badge-downloaded"><?php esc_html_e( 'Downloaded', 'maple-icons' ); ?></span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-set-meta">
|
||||||
|
<span class="mi-set-license">
|
||||||
|
<?php
|
||||||
|
/* translators: %s: License name */
|
||||||
|
printf( esc_html__( 'License: %s', 'maple-icons' ), esc_html( $set['license'] ) );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<span class="mi-set-styles">
|
||||||
|
<?php
|
||||||
|
/* translators: %s: Style names */
|
||||||
|
printf( esc_html__( 'Styles: %s', 'maple-icons' ), esc_html( implode( ', ', $set['styles'] ) ) );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php if ( $is_downloaded && $icon_count > 0 ) : ?>
|
||||||
|
<span class="mi-set-count">
|
||||||
|
<?php
|
||||||
|
/* translators: %d: Number of icons */
|
||||||
|
printf( esc_html( _n( '%d icon', '%d icons', $icon_count, 'maple-icons' ) ), intval( $icon_count ) );
|
||||||
|
?>
|
||||||
|
</span>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<?php if ( ! empty( $set['url'] ) ) : ?>
|
||||||
|
<a href="<?php echo esc_url( $set['url'] ); ?>" class="mi-set-link" target="_blank" rel="noopener noreferrer">
|
||||||
|
<?php esc_html_e( 'View on website', 'maple-icons' ); ?> →
|
||||||
|
</a>
|
||||||
|
<?php endif; ?>
|
||||||
|
|
||||||
|
<div class="mi-set-actions">
|
||||||
|
<?php if ( ! $is_downloaded ) : ?>
|
||||||
|
<button type="button" class="button button-primary mi-download-btn" data-slug="<?php echo esc_attr( $slug ); ?>">
|
||||||
|
<?php esc_html_e( 'Download', 'maple-icons' ); ?>
|
||||||
|
</button>
|
||||||
|
<?php else : ?>
|
||||||
|
<?php if ( ! $is_active ) : ?>
|
||||||
|
<button type="button" class="button button-primary mi-activate-btn" data-slug="<?php echo esc_attr( $slug ); ?>">
|
||||||
|
<?php esc_html_e( 'Set Active', 'maple-icons' ); ?>
|
||||||
|
</button>
|
||||||
|
<?php else : ?>
|
||||||
|
<button type="button" class="button mi-deactivate-btn" data-slug="">
|
||||||
|
<?php esc_html_e( 'Deactivate', 'maple-icons' ); ?>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
<button type="button" class="button mi-delete-btn" data-slug="<?php echo esc_attr( $slug ); ?>">
|
||||||
|
<?php esc_html_e( 'Delete', 'maple-icons' ); ?>
|
||||||
|
</button>
|
||||||
|
<?php endif; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-set-progress" style="display: none;">
|
||||||
|
<div class="mi-progress-bar">
|
||||||
|
<div class="mi-progress-fill"></div>
|
||||||
|
</div>
|
||||||
|
<span class="mi-progress-text"></span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-set-message" style="display: none;"></div>
|
||||||
|
</div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-admin-usage">
|
||||||
|
<h2><?php esc_html_e( 'How to Use', 'maple-icons' ); ?></h2>
|
||||||
|
<ol>
|
||||||
|
<li><?php esc_html_e( 'Download one or more icon sets above.', 'maple-icons' ); ?></li>
|
||||||
|
<li><?php esc_html_e( 'Set one icon set as active.', 'maple-icons' ); ?></li>
|
||||||
|
<li><?php esc_html_e( 'In the Gutenberg editor, add a "Maple Icon" block.', 'maple-icons' ); ?></li>
|
||||||
|
<li><?php esc_html_e( 'Search and select an icon from your active set.', 'maple-icons' ); ?></li>
|
||||||
|
<li><?php esc_html_e( 'Customize size, color, and other settings in the block sidebar.', 'maple-icons' ); ?></li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mi-admin-info">
|
||||||
|
<h2><?php esc_html_e( 'About', 'maple-icons' ); ?></h2>
|
||||||
|
<p>
|
||||||
|
<?php esc_html_e( 'Maple Icons downloads SVG icons from CDN and stores them locally in your WordPress installation. Icons are sanitized for security and normalized for consistent rendering.', 'maple-icons' ); ?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<?php esc_html_e( 'All icons use currentColor for styling, which means they automatically inherit text color from your theme or block settings.', 'maple-icons' ); ?>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<?php
|
||||||
|
printf(
|
||||||
|
/* translators: %s: Directory path */
|
||||||
|
esc_html__( 'Icons are stored in: %s', 'maple-icons' ),
|
||||||
|
'<code>' . esc_html( MI_ICONS_DIR ) . '</code>'
|
||||||
|
);
|
||||||
|
?>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<?php
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,376 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* AJAX Handler class - Handles all AJAX requests.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MI_Ajax_Handler
|
||||||
|
*
|
||||||
|
* Handles all AJAX requests for the plugin.
|
||||||
|
*/
|
||||||
|
class MI_Ajax_Handler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor - Register AJAX handlers.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
// Admin AJAX handlers.
|
||||||
|
add_action( 'wp_ajax_mi_download_set', array( $this, 'handle_download_set' ) );
|
||||||
|
add_action( 'wp_ajax_mi_delete_set', array( $this, 'handle_delete_set' ) );
|
||||||
|
add_action( 'wp_ajax_mi_set_active', array( $this, 'handle_set_active' ) );
|
||||||
|
add_action( 'wp_ajax_mi_get_progress', array( $this, 'handle_get_progress' ) );
|
||||||
|
|
||||||
|
// Block editor AJAX handlers.
|
||||||
|
add_action( 'wp_ajax_mi_search_icons', array( $this, 'handle_search_icons' ) );
|
||||||
|
add_action( 'wp_ajax_mi_get_icon_svg', array( $this, 'handle_get_icon_svg' ) );
|
||||||
|
|
||||||
|
// No nopriv handlers - all functionality requires login.
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle download set request.
|
||||||
|
*/
|
||||||
|
public function handle_download_set() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check.
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||||
|
|
||||||
|
if ( empty( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Icon set slug is required.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if already downloaded.
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
if ( $registry->is_downloaded( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'This icon set is already downloaded.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Process download.
|
||||||
|
// Increase time limit for large downloads.
|
||||||
|
set_time_limit( 600 ); // 10 minutes.
|
||||||
|
|
||||||
|
$downloader = new MI_Downloader();
|
||||||
|
$result = $downloader->download_set( $slug );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => $result->get_error_message() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $result['success'] ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array(
|
||||||
|
'message' => sprintf(
|
||||||
|
/* translators: %1$d: downloaded count, %2$d: failed count */
|
||||||
|
__( 'Download completed with errors. %1$d downloaded, %2$d failed.', 'maple-icons' ),
|
||||||
|
$result['downloaded'],
|
||||||
|
$result['failed']
|
||||||
|
),
|
||||||
|
'errors' => array_slice( $result['errors'], 0, 10 ), // Limit errors shown.
|
||||||
|
'downloaded' => $result['downloaded'],
|
||||||
|
'failed' => $result['failed'],
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark as downloaded.
|
||||||
|
$registry->mark_downloaded( $slug, $result['downloaded'] );
|
||||||
|
|
||||||
|
// If no active set, make this one active.
|
||||||
|
if ( ! $registry->get_active_set() ) {
|
||||||
|
$registry->set_active( $slug );
|
||||||
|
}
|
||||||
|
|
||||||
|
$registry->refresh();
|
||||||
|
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'message' => sprintf(
|
||||||
|
/* translators: %d: number of icons */
|
||||||
|
__( 'Successfully downloaded %d icons.', 'maple-icons' ),
|
||||||
|
$result['downloaded']
|
||||||
|
),
|
||||||
|
'icon_count' => $result['downloaded'],
|
||||||
|
'is_active' => $registry->get_active_set() === $slug,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle delete set request.
|
||||||
|
*/
|
||||||
|
public function handle_delete_set() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check.
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||||
|
|
||||||
|
if ( empty( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Icon set slug is required.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Delete the set.
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
$result = $registry->delete_set( $slug );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => $result->get_error_message() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'message' => __( 'Icon set deleted successfully.', 'maple-icons' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle set active request.
|
||||||
|
*/
|
||||||
|
public function handle_set_active() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check.
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||||
|
|
||||||
|
// Empty slug is allowed (to deactivate).
|
||||||
|
if ( ! empty( $slug ) && ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Set active.
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
$result = $registry->set_active( $slug );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => $result->get_error_message() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'message' => empty( $slug )
|
||||||
|
? __( 'No icon set is now active.', 'maple-icons' )
|
||||||
|
: __( 'Icon set activated.', 'maple-icons' ),
|
||||||
|
'active_set' => $slug,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle get progress request.
|
||||||
|
*/
|
||||||
|
public function handle_get_progress() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_admin_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check.
|
||||||
|
if ( ! current_user_can( 'manage_options' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$slug = isset( $_POST['slug'] ) ? sanitize_key( $_POST['slug'] ) : '';
|
||||||
|
|
||||||
|
if ( empty( $slug ) || ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Invalid icon set.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Get progress.
|
||||||
|
$downloader = new MI_Downloader();
|
||||||
|
$progress = $downloader->get_progress( $slug );
|
||||||
|
|
||||||
|
if ( false === $progress ) {
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'downloading' => false,
|
||||||
|
'completed' => 0,
|
||||||
|
'total' => 0,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'downloading' => true,
|
||||||
|
'completed' => $progress['completed'],
|
||||||
|
'total' => $progress['total'],
|
||||||
|
'percentage' => $progress['total'] > 0
|
||||||
|
? round( ( $progress['completed'] / $progress['total'] ) * 100 )
|
||||||
|
: 0,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle search icons request (for block editor).
|
||||||
|
*/
|
||||||
|
public function handle_search_icons() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_block_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check (edit_posts for block usage).
|
||||||
|
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$query = isset( $_POST['query'] ) ? sanitize_text_field( $_POST['query'] ) : '';
|
||||||
|
$style = isset( $_POST['style'] ) ? sanitize_key( $_POST['style'] ) : '';
|
||||||
|
$limit = isset( $_POST['limit'] ) ? absint( $_POST['limit'] ) : MI_SEARCH_LIMIT;
|
||||||
|
$offset = isset( $_POST['offset'] ) ? absint( $_POST['offset'] ) : 0;
|
||||||
|
|
||||||
|
// Limit the limit.
|
||||||
|
if ( $limit > 100 ) {
|
||||||
|
$limit = 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Search.
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
$results = $registry->search_icons( $query, $style, $limit, $offset );
|
||||||
|
|
||||||
|
wp_send_json_success( $results );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle get icon SVG request (for block editor).
|
||||||
|
*/
|
||||||
|
public function handle_get_icon_svg() {
|
||||||
|
// 1. Nonce verification.
|
||||||
|
if ( ! check_ajax_referer( 'mi_block_nonce', 'nonce', false ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Security check failed.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Capability check.
|
||||||
|
if ( ! current_user_can( 'edit_posts' ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'You do not have permission to do this.', 'maple-icons' ) ),
|
||||||
|
403
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Input validation.
|
||||||
|
$slug = isset( $_POST['set'] ) ? sanitize_key( $_POST['set'] ) : '';
|
||||||
|
$style = isset( $_POST['style'] ) ? sanitize_key( $_POST['style'] ) : '';
|
||||||
|
$name = isset( $_POST['name'] ) ? sanitize_file_name( $_POST['name'] ) : '';
|
||||||
|
|
||||||
|
if ( empty( $slug ) || empty( $style ) || empty( $name ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => __( 'Missing required parameters.', 'maple-icons' ) )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. Get SVG.
|
||||||
|
$registry = MI_Icon_Registry::get_instance();
|
||||||
|
$svg = $registry->get_icon_svg( $slug, $style, $name );
|
||||||
|
|
||||||
|
if ( is_wp_error( $svg ) ) {
|
||||||
|
wp_send_json_error(
|
||||||
|
array( 'message' => $svg->get_error_message() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_send_json_success(
|
||||||
|
array(
|
||||||
|
'svg' => $svg,
|
||||||
|
'set' => $slug,
|
||||||
|
'style' => $style,
|
||||||
|
'name' => $name,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
505
native/wordpress/maple-icons-wp/includes/class-mi-downloader.php
Normal file
505
native/wordpress/maple-icons-wp/includes/class-mi-downloader.php
Normal file
|
|
@ -0,0 +1,505 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Downloader class - Handles fetching icons from CDN and storing locally.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MI_Downloader
|
||||||
|
*
|
||||||
|
* Downloads icon sets from CDN and stores them locally.
|
||||||
|
*/
|
||||||
|
class MI_Downloader {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allowed SVG elements for sanitization.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
private static $allowed_svg_elements = array(
|
||||||
|
'svg' => array(
|
||||||
|
'xmlns' => true,
|
||||||
|
'viewbox' => true,
|
||||||
|
'width' => true,
|
||||||
|
'height' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'stroke-linecap' => true,
|
||||||
|
'stroke-linejoin' => true,
|
||||||
|
'class' => true,
|
||||||
|
'aria-hidden' => true,
|
||||||
|
'role' => true,
|
||||||
|
'focusable' => true,
|
||||||
|
'style' => true,
|
||||||
|
),
|
||||||
|
'path' => array(
|
||||||
|
'd' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'stroke-linecap' => true,
|
||||||
|
'stroke-linejoin' => true,
|
||||||
|
'fill-rule' => true,
|
||||||
|
'clip-rule' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
'fill-opacity' => true,
|
||||||
|
'stroke-opacity' => true,
|
||||||
|
),
|
||||||
|
'circle' => array(
|
||||||
|
'cx' => true,
|
||||||
|
'cy' => true,
|
||||||
|
'r' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'rect' => array(
|
||||||
|
'x' => true,
|
||||||
|
'y' => true,
|
||||||
|
'width' => true,
|
||||||
|
'height' => true,
|
||||||
|
'rx' => true,
|
||||||
|
'ry' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'line' => array(
|
||||||
|
'x1' => true,
|
||||||
|
'y1' => true,
|
||||||
|
'x2' => true,
|
||||||
|
'y2' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'stroke-linecap' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'polyline' => array(
|
||||||
|
'points' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'stroke-linecap' => true,
|
||||||
|
'stroke-linejoin' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'polygon' => array(
|
||||||
|
'points' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'ellipse' => array(
|
||||||
|
'cx' => true,
|
||||||
|
'cy' => true,
|
||||||
|
'rx' => true,
|
||||||
|
'ry' => true,
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'g' => array(
|
||||||
|
'fill' => true,
|
||||||
|
'stroke' => true,
|
||||||
|
'stroke-width' => true,
|
||||||
|
'transform' => true,
|
||||||
|
'opacity' => true,
|
||||||
|
),
|
||||||
|
'defs' => array(),
|
||||||
|
'clippath' => array(
|
||||||
|
'id' => true,
|
||||||
|
),
|
||||||
|
'use' => array(
|
||||||
|
'href' => true,
|
||||||
|
'xlink:href' => true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download an entire icon set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param callable|null $progress_callback Optional progress callback.
|
||||||
|
* @return array|WP_Error Download results or error.
|
||||||
|
*/
|
||||||
|
public function download_set( $slug, $progress_callback = null ) {
|
||||||
|
// Validate slug.
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'invalid_set',
|
||||||
|
__( 'Invalid icon set.', 'maple-icons' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$set_config = MI_Icon_Sets::get( $slug );
|
||||||
|
$manifest = MI_Icon_Sets::load_manifest( $slug );
|
||||||
|
|
||||||
|
if ( is_wp_error( $manifest ) ) {
|
||||||
|
return $manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create base directory.
|
||||||
|
$base_dir = MI_ICONS_DIR . $slug;
|
||||||
|
if ( ! $this->ensure_directory( $base_dir ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'directory_error',
|
||||||
|
__( 'Could not create icon directory.', 'maple-icons' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create style directories.
|
||||||
|
foreach ( $set_config['styles'] as $style_slug => $style_config ) {
|
||||||
|
$style_dir = $base_dir . '/' . $style_slug;
|
||||||
|
if ( ! $this->ensure_directory( $style_dir ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'directory_error',
|
||||||
|
__( 'Could not create style directory.', 'maple-icons' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$icons = isset( $manifest['icons'] ) ? $manifest['icons'] : array();
|
||||||
|
$total_icons = count( $icons );
|
||||||
|
$downloaded = 0;
|
||||||
|
$failed = 0;
|
||||||
|
$errors = array();
|
||||||
|
$total_to_download = 0;
|
||||||
|
|
||||||
|
// Calculate total icons to download (icon × styles).
|
||||||
|
foreach ( $icons as $icon ) {
|
||||||
|
$icon_styles = isset( $icon['styles'] ) ? $icon['styles'] : array_keys( $set_config['styles'] );
|
||||||
|
$total_to_download += count( $icon_styles );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize progress transient.
|
||||||
|
set_transient(
|
||||||
|
'mi_download_progress_' . $slug,
|
||||||
|
array(
|
||||||
|
'completed' => 0,
|
||||||
|
'total' => $total_to_download,
|
||||||
|
'status' => 'downloading',
|
||||||
|
),
|
||||||
|
HOUR_IN_SECONDS
|
||||||
|
);
|
||||||
|
|
||||||
|
$current = 0;
|
||||||
|
|
||||||
|
// Download each icon.
|
||||||
|
foreach ( $icons as $icon ) {
|
||||||
|
$icon_name = $icon['name'];
|
||||||
|
$icon_styles = isset( $icon['styles'] ) ? $icon['styles'] : array_keys( $set_config['styles'] );
|
||||||
|
|
||||||
|
foreach ( $icon_styles as $style ) {
|
||||||
|
if ( ! isset( $set_config['styles'][ $style ] ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = $this->download_icon( $slug, $style, $icon_name );
|
||||||
|
|
||||||
|
if ( is_wp_error( $result ) ) {
|
||||||
|
$failed++;
|
||||||
|
$errors[] = sprintf( '%s/%s: %s', $style, $icon_name, $result->get_error_message() );
|
||||||
|
} else {
|
||||||
|
$downloaded++;
|
||||||
|
}
|
||||||
|
|
||||||
|
$current++;
|
||||||
|
|
||||||
|
// Update progress.
|
||||||
|
set_transient(
|
||||||
|
'mi_download_progress_' . $slug,
|
||||||
|
array(
|
||||||
|
'completed' => $current,
|
||||||
|
'total' => $total_to_download,
|
||||||
|
'status' => 'downloading',
|
||||||
|
),
|
||||||
|
HOUR_IN_SECONDS
|
||||||
|
);
|
||||||
|
|
||||||
|
// Call progress callback if provided.
|
||||||
|
if ( is_callable( $progress_callback ) ) {
|
||||||
|
call_user_func( $progress_callback, $current, $total_to_download );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow some breathing room for the server.
|
||||||
|
if ( 0 === $current % MI_DOWNLOAD_BATCH_SIZE ) {
|
||||||
|
usleep( 100000 ); // 100ms pause every batch.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear progress transient.
|
||||||
|
delete_transient( 'mi_download_progress_' . $slug );
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'success' => $failed === 0,
|
||||||
|
'downloaded' => $downloaded,
|
||||||
|
'failed' => $failed,
|
||||||
|
'total' => $total_to_download,
|
||||||
|
'errors' => $errors,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Download a single icon from CDN.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @param string $name Icon name.
|
||||||
|
* @return string|WP_Error Local file path or error.
|
||||||
|
*/
|
||||||
|
public function download_icon( $slug, $style, $name ) {
|
||||||
|
// Validate inputs.
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return new WP_Error( 'invalid_set', __( 'Invalid icon set.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_style( $slug, $style ) ) {
|
||||||
|
return new WP_Error( 'invalid_style', __( 'Invalid icon style.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate icon name (only allow alphanumeric, hyphens, underscores).
|
||||||
|
if ( ! preg_match( '/^[a-z0-9\-_]+$/i', $name ) ) {
|
||||||
|
return new WP_Error( 'invalid_name', __( 'Invalid icon name.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$cdn_url = MI_Icon_Sets::get_cdn_url( $slug, $style, $name );
|
||||||
|
$local_path = MI_Icon_Sets::get_local_path( $slug, $style, $name );
|
||||||
|
|
||||||
|
// Check if already downloaded.
|
||||||
|
if ( file_exists( $local_path ) ) {
|
||||||
|
return $local_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch from CDN.
|
||||||
|
$response = wp_remote_get(
|
||||||
|
$cdn_url,
|
||||||
|
array(
|
||||||
|
'timeout' => MI_DOWNLOAD_TIMEOUT,
|
||||||
|
'sslverify' => true,
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( is_wp_error( $response ) ) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
|
||||||
|
$status_code = wp_remote_retrieve_response_code( $response );
|
||||||
|
if ( 200 !== $status_code ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'cdn_error',
|
||||||
|
sprintf(
|
||||||
|
/* translators: %d: HTTP status code */
|
||||||
|
__( 'CDN returned status %d.', 'maple-icons' ),
|
||||||
|
$status_code
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$svg_content = wp_remote_retrieve_body( $response );
|
||||||
|
if ( empty( $svg_content ) ) {
|
||||||
|
return new WP_Error( 'empty_response', __( 'Empty response from CDN.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get set config for normalization.
|
||||||
|
$set_config = MI_Icon_Sets::get( $slug );
|
||||||
|
|
||||||
|
// Normalize and sanitize SVG.
|
||||||
|
$svg_content = $this->normalize_svg( $svg_content, $set_config );
|
||||||
|
$svg_content = $this->sanitize_svg( $svg_content );
|
||||||
|
|
||||||
|
if ( empty( $svg_content ) ) {
|
||||||
|
return new WP_Error( 'invalid_svg', __( 'Invalid or empty SVG content.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure directory exists.
|
||||||
|
$dir = dirname( $local_path );
|
||||||
|
if ( ! $this->ensure_directory( $dir ) ) {
|
||||||
|
return new WP_Error( 'directory_error', __( 'Could not create directory.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write file.
|
||||||
|
global $wp_filesystem;
|
||||||
|
if ( empty( $wp_filesystem ) ) {
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/file.php';
|
||||||
|
WP_Filesystem();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $wp_filesystem->put_contents( $local_path, $svg_content, FS_CHMOD_FILE ) ) {
|
||||||
|
return new WP_Error( 'write_error', __( 'Could not write SVG file.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $local_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normalize SVG content based on set configuration.
|
||||||
|
*
|
||||||
|
* @param string $svg SVG content.
|
||||||
|
* @param array $set_config Icon set configuration.
|
||||||
|
* @return string Normalized SVG content.
|
||||||
|
*/
|
||||||
|
private function normalize_svg( $svg, $set_config ) {
|
||||||
|
// Strip XML declaration.
|
||||||
|
$svg = preg_replace( '/<\?xml[^>]*\?>/i', '', $svg );
|
||||||
|
|
||||||
|
// Strip DOCTYPE.
|
||||||
|
$svg = preg_replace( '/<!DOCTYPE[^>]*>/i', '', $svg );
|
||||||
|
|
||||||
|
// Strip comments.
|
||||||
|
$svg = preg_replace( '/<!--.*?-->/s', '', $svg );
|
||||||
|
|
||||||
|
// Strip title and desc elements.
|
||||||
|
$svg = preg_replace( '/<title[^>]*>.*?<\/title>/is', '', $svg );
|
||||||
|
$svg = preg_replace( '/<desc[^>]*>.*?<\/desc>/is', '', $svg );
|
||||||
|
|
||||||
|
// Normalize viewBox for Phosphor (256 → 24).
|
||||||
|
if ( ! empty( $set_config['normalize'] ) ) {
|
||||||
|
$svg = preg_replace(
|
||||||
|
'/viewBox=["\']0\s+0\s+256\s+256["\']/i',
|
||||||
|
'viewBox="0 0 24 24"',
|
||||||
|
$svg
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fix hardcoded colors for Material.
|
||||||
|
if ( ! empty( $set_config['color_fix'] ) ) {
|
||||||
|
// Replace hardcoded hex colors.
|
||||||
|
$svg = preg_replace( '/fill=["\']#[0-9a-fA-F]{3,6}["\']/', 'fill="currentColor"', $svg );
|
||||||
|
$svg = preg_replace( '/fill=["\']black["\']/', 'fill="currentColor"', $svg );
|
||||||
|
$svg = preg_replace( '/fill=["\']rgb\([^)]+\)["\']/', 'fill="currentColor"', $svg );
|
||||||
|
|
||||||
|
// Same for stroke.
|
||||||
|
$svg = preg_replace( '/stroke=["\']#[0-9a-fA-F]{3,6}["\']/', 'stroke="currentColor"', $svg );
|
||||||
|
$svg = preg_replace( '/stroke=["\']black["\']/', 'stroke="currentColor"', $svg );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove width/height attributes (let CSS control size).
|
||||||
|
$svg = preg_replace( '/\s(width|height)=["\'][^"\']*["\']/i', '', $svg );
|
||||||
|
|
||||||
|
// Ensure there's no leading/trailing whitespace.
|
||||||
|
$svg = trim( $svg );
|
||||||
|
|
||||||
|
return $svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sanitize SVG content to remove potentially dangerous elements.
|
||||||
|
*
|
||||||
|
* @param string $svg SVG content.
|
||||||
|
* @return string Sanitized SVG content.
|
||||||
|
*/
|
||||||
|
private function sanitize_svg( $svg ) {
|
||||||
|
// Remove script tags.
|
||||||
|
$svg = preg_replace( '/<script\b[^>]*>.*?<\/script>/is', '', $svg );
|
||||||
|
|
||||||
|
// Remove event handlers.
|
||||||
|
$svg = preg_replace( '/\s+on\w+\s*=/i', ' data-removed=', $svg );
|
||||||
|
|
||||||
|
// Remove javascript: URLs.
|
||||||
|
$svg = preg_replace( '/javascript:/i', 'removed:', $svg );
|
||||||
|
|
||||||
|
// Remove data: URLs (except for certain safe uses).
|
||||||
|
$svg = preg_replace( '/data:[^"\'>\s]+/i', 'removed:', $svg );
|
||||||
|
|
||||||
|
// Use WordPress kses with our allowed tags.
|
||||||
|
$svg = wp_kses( $svg, self::$allowed_svg_elements );
|
||||||
|
|
||||||
|
// Verify it's still a valid SVG.
|
||||||
|
if ( strpos( $svg, '<svg' ) === false || strpos( $svg, '</svg>' ) === false ) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensure a directory exists, creating it if necessary.
|
||||||
|
*
|
||||||
|
* @param string $dir Directory path.
|
||||||
|
* @return bool True if directory exists or was created.
|
||||||
|
*/
|
||||||
|
private function ensure_directory( $dir ) {
|
||||||
|
if ( file_exists( $dir ) ) {
|
||||||
|
return is_dir( $dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
return wp_mkdir_p( $dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all icons for a set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return bool True on success.
|
||||||
|
*/
|
||||||
|
public function delete_set( $slug ) {
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$set_dir = MI_ICONS_DIR . $slug;
|
||||||
|
|
||||||
|
// Validate the path is within our icons directory.
|
||||||
|
$real_path = realpath( $set_dir );
|
||||||
|
$allowed_base = realpath( MI_ICONS_DIR );
|
||||||
|
|
||||||
|
if ( false === $real_path || false === $allowed_base ) {
|
||||||
|
// Directory doesn't exist, nothing to delete.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( strpos( $real_path, $allowed_base ) !== 0 ) {
|
||||||
|
// Path traversal attempt.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively delete the directory.
|
||||||
|
return $this->delete_directory( $set_dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively delete a directory.
|
||||||
|
*
|
||||||
|
* @param string $dir Directory path.
|
||||||
|
* @return bool True on success.
|
||||||
|
*/
|
||||||
|
private function delete_directory( $dir ) {
|
||||||
|
if ( ! is_dir( $dir ) ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = array_diff( scandir( $dir ), array( '.', '..' ) );
|
||||||
|
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
$path = $dir . '/' . $file;
|
||||||
|
if ( is_dir( $path ) ) {
|
||||||
|
$this->delete_directory( $path );
|
||||||
|
} else {
|
||||||
|
wp_delete_file( $path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rmdir( $dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get download progress for a set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return array|false Progress data or false if not downloading.
|
||||||
|
*/
|
||||||
|
public function get_progress( $slug ) {
|
||||||
|
return get_transient( 'mi_download_progress_' . $slug );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,416 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Icon Registry class - Manages downloaded sets and provides icon search/retrieval.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MI_Icon_Registry
|
||||||
|
*
|
||||||
|
* Manages downloaded icon sets and provides search/retrieval functionality.
|
||||||
|
*/
|
||||||
|
class MI_Icon_Registry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton instance.
|
||||||
|
*
|
||||||
|
* @var MI_Icon_Registry|null
|
||||||
|
*/
|
||||||
|
private static $instance = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached settings.
|
||||||
|
*
|
||||||
|
* @var array|null
|
||||||
|
*/
|
||||||
|
private $settings = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get singleton instance.
|
||||||
|
*
|
||||||
|
* @return MI_Icon_Registry
|
||||||
|
*/
|
||||||
|
public static function get_instance() {
|
||||||
|
if ( null === self::$instance ) {
|
||||||
|
self::$instance = new self();
|
||||||
|
}
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
private function __construct() {
|
||||||
|
$this->load_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load settings from database.
|
||||||
|
*/
|
||||||
|
private function load_settings() {
|
||||||
|
$this->settings = get_option(
|
||||||
|
'maple_icons_settings',
|
||||||
|
array(
|
||||||
|
'active_set' => '',
|
||||||
|
'downloaded_sets' => array(),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save settings to database.
|
||||||
|
*
|
||||||
|
* @return bool True on success.
|
||||||
|
*/
|
||||||
|
private function save_settings() {
|
||||||
|
return update_option( 'maple_icons_settings', $this->settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all downloaded sets.
|
||||||
|
*
|
||||||
|
* @return array Array of downloaded set data.
|
||||||
|
*/
|
||||||
|
public function get_downloaded_sets() {
|
||||||
|
return isset( $this->settings['downloaded_sets'] ) ? $this->settings['downloaded_sets'] : array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the active set slug.
|
||||||
|
*
|
||||||
|
* @return string|null Active set slug or null if none.
|
||||||
|
*/
|
||||||
|
public function get_active_set() {
|
||||||
|
$active = isset( $this->settings['active_set'] ) ? $this->settings['active_set'] : '';
|
||||||
|
return ! empty( $active ) ? $active : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the active icon set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return bool|WP_Error True on success, error on failure.
|
||||||
|
*/
|
||||||
|
public function set_active( $slug ) {
|
||||||
|
// Allow empty string to deactivate.
|
||||||
|
if ( empty( $slug ) ) {
|
||||||
|
$this->settings['active_set'] = '';
|
||||||
|
return $this->save_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate slug.
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return new WP_Error( 'invalid_set', __( 'Invalid icon set.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if downloaded.
|
||||||
|
if ( ! $this->is_downloaded( $slug ) ) {
|
||||||
|
return new WP_Error( 'not_downloaded', __( 'Icon set is not downloaded.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->settings['active_set'] = $slug;
|
||||||
|
return $this->save_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if a set is downloaded.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return bool True if downloaded.
|
||||||
|
*/
|
||||||
|
public function is_downloaded( $slug ) {
|
||||||
|
$downloaded = $this->get_downloaded_sets();
|
||||||
|
return isset( $downloaded[ $slug ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a set as downloaded.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param int $icon_count Number of icons downloaded.
|
||||||
|
* @return bool True on success.
|
||||||
|
*/
|
||||||
|
public function mark_downloaded( $slug, $icon_count ) {
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$set_config = MI_Icon_Sets::get( $slug );
|
||||||
|
|
||||||
|
$this->settings['downloaded_sets'][ $slug ] = array(
|
||||||
|
'version' => $set_config['version'],
|
||||||
|
'downloaded_at' => current_time( 'mysql' ),
|
||||||
|
'icon_count' => $icon_count,
|
||||||
|
);
|
||||||
|
|
||||||
|
return $this->save_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a set from downloaded list.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return bool True on success.
|
||||||
|
*/
|
||||||
|
public function unmark_downloaded( $slug ) {
|
||||||
|
if ( isset( $this->settings['downloaded_sets'][ $slug ] ) ) {
|
||||||
|
unset( $this->settings['downloaded_sets'][ $slug ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this was the active set, clear it.
|
||||||
|
if ( $this->settings['active_set'] === $slug ) {
|
||||||
|
$this->settings['active_set'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->save_settings();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all icons for a set and style.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @return array Array of icon data.
|
||||||
|
*/
|
||||||
|
public function get_icons_for_set( $slug, $style ) {
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_style( $slug, $style ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load manifest.
|
||||||
|
$manifest = MI_Icon_Sets::load_manifest( $slug );
|
||||||
|
if ( is_wp_error( $manifest ) ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$icons = isset( $manifest['icons'] ) ? $manifest['icons'] : array();
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
foreach ( $icons as $icon ) {
|
||||||
|
$icon_styles = isset( $icon['styles'] ) ? $icon['styles'] : array_keys( MI_Icon_Sets::get( $slug )['styles'] );
|
||||||
|
|
||||||
|
// Only include if this icon has the requested style.
|
||||||
|
if ( in_array( $style, $icon_styles, true ) ) {
|
||||||
|
$result[] = array(
|
||||||
|
'name' => $icon['name'],
|
||||||
|
'tags' => isset( $icon['tags'] ) ? $icon['tags'] : array(),
|
||||||
|
'category' => isset( $icon['category'] ) ? $icon['category'] : '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Search icons in the active set.
|
||||||
|
*
|
||||||
|
* @param string $query Search query.
|
||||||
|
* @param string $style Optional style filter.
|
||||||
|
* @param int $limit Maximum results.
|
||||||
|
* @param int $offset Offset for pagination.
|
||||||
|
* @return array Search results.
|
||||||
|
*/
|
||||||
|
public function search_icons( $query = '', $style = '', $limit = MI_SEARCH_LIMIT, $offset = 0 ) {
|
||||||
|
$active_set = $this->get_active_set();
|
||||||
|
if ( ! $active_set ) {
|
||||||
|
return array(
|
||||||
|
'icons' => array(),
|
||||||
|
'total' => 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$set_config = MI_Icon_Sets::get( $active_set );
|
||||||
|
if ( ! $set_config ) {
|
||||||
|
return array(
|
||||||
|
'icons' => array(),
|
||||||
|
'total' => 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default to first style if not specified.
|
||||||
|
if ( empty( $style ) ) {
|
||||||
|
$style = $set_config['default_style'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate style.
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_style( $active_set, $style ) ) {
|
||||||
|
$style = $set_config['default_style'];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load manifest.
|
||||||
|
$manifest = MI_Icon_Sets::load_manifest( $active_set );
|
||||||
|
if ( is_wp_error( $manifest ) ) {
|
||||||
|
return array(
|
||||||
|
'icons' => array(),
|
||||||
|
'total' => 0,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$icons = isset( $manifest['icons'] ) ? $manifest['icons'] : array();
|
||||||
|
$query = strtolower( trim( $query ) );
|
||||||
|
$results = array();
|
||||||
|
|
||||||
|
foreach ( $icons as $icon ) {
|
||||||
|
$icon_styles = isset( $icon['styles'] ) ? $icon['styles'] : array_keys( $set_config['styles'] );
|
||||||
|
|
||||||
|
// Skip if this icon doesn't have the requested style.
|
||||||
|
if ( ! in_array( $style, $icon_styles, true ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no query, include all.
|
||||||
|
if ( empty( $query ) ) {
|
||||||
|
$results[] = $icon;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in name.
|
||||||
|
if ( strpos( strtolower( $icon['name'] ), $query ) !== false ) {
|
||||||
|
$results[] = $icon;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search in tags.
|
||||||
|
if ( isset( $icon['tags'] ) && is_array( $icon['tags'] ) ) {
|
||||||
|
foreach ( $icon['tags'] as $tag ) {
|
||||||
|
if ( strpos( strtolower( $tag ), $query ) !== false ) {
|
||||||
|
$results[] = $icon;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$total = count( $results );
|
||||||
|
|
||||||
|
// Apply offset and limit.
|
||||||
|
$results = array_slice( $results, $offset, $limit );
|
||||||
|
|
||||||
|
// Format results.
|
||||||
|
$formatted = array();
|
||||||
|
foreach ( $results as $icon ) {
|
||||||
|
$formatted[] = array(
|
||||||
|
'name' => $icon['name'],
|
||||||
|
'tags' => isset( $icon['tags'] ) ? $icon['tags'] : array(),
|
||||||
|
'category' => isset( $icon['category'] ) ? $icon['category'] : '',
|
||||||
|
'set' => $active_set,
|
||||||
|
'style' => $style,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'icons' => $formatted,
|
||||||
|
'total' => $total,
|
||||||
|
'set' => $active_set,
|
||||||
|
'style' => $style,
|
||||||
|
'styles' => MI_Icon_Sets::get_style_labels( $active_set ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get SVG content for a specific icon.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @param string $name Icon name.
|
||||||
|
* @return string|WP_Error SVG content or error.
|
||||||
|
*/
|
||||||
|
public function get_icon_svg( $slug, $style, $name ) {
|
||||||
|
// Validate inputs.
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return new WP_Error( 'invalid_set', __( 'Invalid icon set.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_style( $slug, $style ) ) {
|
||||||
|
return new WP_Error( 'invalid_style', __( 'Invalid icon style.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate icon name.
|
||||||
|
if ( ! preg_match( '/^[a-z0-9\-_]+$/i', $name ) ) {
|
||||||
|
return new WP_Error( 'invalid_name', __( 'Invalid icon name.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$local_path = MI_Icon_Sets::get_local_path( $slug, $style, $name );
|
||||||
|
|
||||||
|
// Validate path is within icons directory (prevent path traversal).
|
||||||
|
$real_path = realpath( $local_path );
|
||||||
|
$allowed_base = realpath( MI_ICONS_DIR );
|
||||||
|
|
||||||
|
if ( false === $real_path ) {
|
||||||
|
return new WP_Error( 'not_found', __( 'Icon not found.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( false === $allowed_base || strpos( $real_path, $allowed_base ) !== 0 ) {
|
||||||
|
return new WP_Error( 'invalid_path', __( 'Invalid icon path.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! file_exists( $real_path ) ) {
|
||||||
|
return new WP_Error( 'not_found', __( 'Icon not found.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
$svg = file_get_contents( $real_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||||
|
|
||||||
|
if ( false === $svg ) {
|
||||||
|
return new WP_Error( 'read_error', __( 'Could not read icon file.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return $svg;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a downloaded set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return bool|WP_Error True on success, error on failure.
|
||||||
|
*/
|
||||||
|
public function delete_set( $slug ) {
|
||||||
|
if ( ! MI_Icon_Sets::is_valid_slug( $slug ) ) {
|
||||||
|
return new WP_Error( 'invalid_set', __( 'Invalid icon set.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $this->is_downloaded( $slug ) ) {
|
||||||
|
return new WP_Error( 'not_downloaded', __( 'Icon set is not downloaded.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete files.
|
||||||
|
$downloader = new MI_Downloader();
|
||||||
|
$deleted = $downloader->delete_set( $slug );
|
||||||
|
|
||||||
|
if ( ! $deleted ) {
|
||||||
|
return new WP_Error( 'delete_error', __( 'Could not delete icon files.', 'maple-icons' ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update settings.
|
||||||
|
$this->unmark_downloaded( $slug );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get info about a downloaded set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return array|null Set info or null if not downloaded.
|
||||||
|
*/
|
||||||
|
public function get_downloaded_info( $slug ) {
|
||||||
|
$downloaded = $this->get_downloaded_sets();
|
||||||
|
return isset( $downloaded[ $slug ] ) ? $downloaded[ $slug ] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Refresh settings from database.
|
||||||
|
*/
|
||||||
|
public function refresh() {
|
||||||
|
$this->load_settings();
|
||||||
|
}
|
||||||
|
}
|
||||||
328
native/wordpress/maple-icons-wp/includes/class-mi-icon-sets.php
Normal file
328
native/wordpress/maple-icons-wp/includes/class-mi-icon-sets.php
Normal file
|
|
@ -0,0 +1,328 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Icon Sets class - Static definitions of all preset icon sets.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class MI_Icon_Sets
|
||||||
|
*
|
||||||
|
* Provides static definitions and utilities for preset icon sets.
|
||||||
|
*/
|
||||||
|
class MI_Icon_Sets {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all available preset icon sets.
|
||||||
|
*
|
||||||
|
* @return array Array of icon set configurations.
|
||||||
|
*/
|
||||||
|
public static function get_all() {
|
||||||
|
return array(
|
||||||
|
'heroicons' => array(
|
||||||
|
'slug' => 'heroicons',
|
||||||
|
'name' => 'Heroicons',
|
||||||
|
'version' => '2.1.1',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'url' => 'https://heroicons.com',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/heroicons@2.1.1/',
|
||||||
|
'styles' => array(
|
||||||
|
'outline' => array(
|
||||||
|
'path' => '24/outline',
|
||||||
|
'label' => 'Outline',
|
||||||
|
),
|
||||||
|
'solid' => array(
|
||||||
|
'path' => '24/solid',
|
||||||
|
'label' => 'Solid',
|
||||||
|
),
|
||||||
|
'mini' => array(
|
||||||
|
'path' => '20/solid',
|
||||||
|
'label' => 'Mini',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'default_style' => 'outline',
|
||||||
|
'viewbox' => '0 0 24 24',
|
||||||
|
'normalize' => false,
|
||||||
|
'color_fix' => false,
|
||||||
|
'description' => 'Beautiful hand-crafted SVG icons by the makers of Tailwind CSS.',
|
||||||
|
'icon_count' => 292,
|
||||||
|
),
|
||||||
|
'lucide' => array(
|
||||||
|
'slug' => 'lucide',
|
||||||
|
'name' => 'Lucide',
|
||||||
|
'version' => '0.303.0',
|
||||||
|
'license' => 'ISC',
|
||||||
|
'url' => 'https://lucide.dev',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/lucide-static@0.303.0/',
|
||||||
|
'styles' => array(
|
||||||
|
'icons' => array(
|
||||||
|
'path' => 'icons',
|
||||||
|
'label' => 'Default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'default_style' => 'icons',
|
||||||
|
'viewbox' => '0 0 24 24',
|
||||||
|
'normalize' => false,
|
||||||
|
'color_fix' => false,
|
||||||
|
'description' => 'Beautiful & consistent icon toolkit made by the community.',
|
||||||
|
'icon_count' => 1411,
|
||||||
|
),
|
||||||
|
'feather' => array(
|
||||||
|
'slug' => 'feather',
|
||||||
|
'name' => 'Feather',
|
||||||
|
'version' => '4.29.1',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'url' => 'https://feathericons.com',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/feather-icons@4.29.1/',
|
||||||
|
'styles' => array(
|
||||||
|
'icons' => array(
|
||||||
|
'path' => 'dist/icons',
|
||||||
|
'label' => 'Default',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'default_style' => 'icons',
|
||||||
|
'viewbox' => '0 0 24 24',
|
||||||
|
'normalize' => false,
|
||||||
|
'color_fix' => false,
|
||||||
|
'description' => 'Simply beautiful open source icons.',
|
||||||
|
'icon_count' => 287,
|
||||||
|
),
|
||||||
|
'phosphor' => array(
|
||||||
|
'slug' => 'phosphor',
|
||||||
|
'name' => 'Phosphor',
|
||||||
|
'version' => '2.1.1',
|
||||||
|
'license' => 'MIT',
|
||||||
|
'url' => 'https://phosphoricons.com',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/@phosphor-icons/core@2.1.1/',
|
||||||
|
'styles' => array(
|
||||||
|
'regular' => array(
|
||||||
|
'path' => 'assets/regular',
|
||||||
|
'label' => 'Regular',
|
||||||
|
),
|
||||||
|
'bold' => array(
|
||||||
|
'path' => 'assets/bold',
|
||||||
|
'label' => 'Bold',
|
||||||
|
),
|
||||||
|
'light' => array(
|
||||||
|
'path' => 'assets/light',
|
||||||
|
'label' => 'Light',
|
||||||
|
),
|
||||||
|
'thin' => array(
|
||||||
|
'path' => 'assets/thin',
|
||||||
|
'label' => 'Thin',
|
||||||
|
),
|
||||||
|
'fill' => array(
|
||||||
|
'path' => 'assets/fill',
|
||||||
|
'label' => 'Fill',
|
||||||
|
),
|
||||||
|
'duotone' => array(
|
||||||
|
'path' => 'assets/duotone',
|
||||||
|
'label' => 'Duotone',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'default_style' => 'regular',
|
||||||
|
'viewbox' => '0 0 256 256',
|
||||||
|
'normalize' => true, // Needs viewBox normalization to 24x24.
|
||||||
|
'color_fix' => false,
|
||||||
|
'description' => 'A flexible icon family for interfaces, diagrams, presentations, and more.',
|
||||||
|
'icon_count' => 1248,
|
||||||
|
),
|
||||||
|
'material' => array(
|
||||||
|
'slug' => 'material',
|
||||||
|
'name' => 'Material Design Icons',
|
||||||
|
'version' => '0.14.13',
|
||||||
|
'license' => 'Apache-2.0',
|
||||||
|
'url' => 'https://fonts.google.com/icons',
|
||||||
|
'cdn_base' => 'https://cdn.jsdelivr.net/npm/@material-design-icons/svg@0.14.13/',
|
||||||
|
'styles' => array(
|
||||||
|
'filled' => array(
|
||||||
|
'path' => 'filled',
|
||||||
|
'label' => 'Filled',
|
||||||
|
),
|
||||||
|
'outlined' => array(
|
||||||
|
'path' => 'outlined',
|
||||||
|
'label' => 'Outlined',
|
||||||
|
),
|
||||||
|
'round' => array(
|
||||||
|
'path' => 'round',
|
||||||
|
'label' => 'Round',
|
||||||
|
),
|
||||||
|
'sharp' => array(
|
||||||
|
'path' => 'sharp',
|
||||||
|
'label' => 'Sharp',
|
||||||
|
),
|
||||||
|
'two-tone' => array(
|
||||||
|
'path' => 'two-tone',
|
||||||
|
'label' => 'Two Tone',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'default_style' => 'filled',
|
||||||
|
'viewbox' => '0 0 24 24',
|
||||||
|
'normalize' => false,
|
||||||
|
'color_fix' => true, // Needs hardcoded color replacement.
|
||||||
|
'description' => 'Material Design Icons by Google. Beautiful, delightful, and easy to use.',
|
||||||
|
'icon_count' => 2189,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a specific icon set by slug.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return array|null Icon set configuration or null if not found.
|
||||||
|
*/
|
||||||
|
public static function get( $slug ) {
|
||||||
|
$sets = self::get_all();
|
||||||
|
return isset( $sets[ $slug ] ) ? $sets[ $slug ] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all available set slugs.
|
||||||
|
*
|
||||||
|
* @return array Array of set slugs.
|
||||||
|
*/
|
||||||
|
public static function get_slugs() {
|
||||||
|
return array_keys( self::get_all() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that a slug is a valid preset.
|
||||||
|
*
|
||||||
|
* @param string $slug Slug to validate.
|
||||||
|
* @return bool True if valid, false otherwise.
|
||||||
|
*/
|
||||||
|
public static function is_valid_slug( $slug ) {
|
||||||
|
return in_array( $slug, self::get_slugs(), true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate that a style is valid for a given set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @return bool True if valid, false otherwise.
|
||||||
|
*/
|
||||||
|
public static function is_valid_style( $slug, $style ) {
|
||||||
|
$set = self::get( $slug );
|
||||||
|
if ( ! $set ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return isset( $set['styles'][ $style ] );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the CDN URL for a specific icon.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @param string $name Icon name.
|
||||||
|
* @return string|null CDN URL or null if invalid.
|
||||||
|
*/
|
||||||
|
public static function get_cdn_url( $slug, $style, $name ) {
|
||||||
|
$set = self::get( $slug );
|
||||||
|
if ( ! $set || ! isset( $set['styles'][ $style ] ) ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$style_config = $set['styles'][ $style ];
|
||||||
|
return $set['cdn_base'] . $style_config['path'] . '/' . $name . '.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local file path for a specific icon.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @param string $name Icon name.
|
||||||
|
* @return string Local file path.
|
||||||
|
*/
|
||||||
|
public static function get_local_path( $slug, $style, $name ) {
|
||||||
|
return MI_ICONS_DIR . $slug . '/' . $style . '/' . $name . '.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the local URL for a specific icon.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @param string $style Style slug.
|
||||||
|
* @param string $name Icon name.
|
||||||
|
* @return string Local URL.
|
||||||
|
*/
|
||||||
|
public static function get_local_url( $slug, $style, $name ) {
|
||||||
|
return MI_ICONS_URL . $slug . '/' . $style . '/' . $name . '.svg';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the manifest file path for a set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return string Manifest file path.
|
||||||
|
*/
|
||||||
|
public static function get_manifest_path( $slug ) {
|
||||||
|
return MI_PRESETS_DIR . $slug . '.json';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load and parse a manifest file.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return array|WP_Error Manifest data or error.
|
||||||
|
*/
|
||||||
|
public static function load_manifest( $slug ) {
|
||||||
|
$path = self::get_manifest_path( $slug );
|
||||||
|
|
||||||
|
if ( ! file_exists( $path ) ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'manifest_not_found',
|
||||||
|
sprintf(
|
||||||
|
/* translators: %s: Icon set name */
|
||||||
|
__( 'Manifest file not found for %s.', 'maple-icons' ),
|
||||||
|
$slug
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$content = file_get_contents( $path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
|
||||||
|
if ( false === $content ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'manifest_read_error',
|
||||||
|
__( 'Could not read manifest file.', 'maple-icons' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
$manifest = json_decode( $content, true );
|
||||||
|
if ( json_last_error() !== JSON_ERROR_NONE ) {
|
||||||
|
return new WP_Error(
|
||||||
|
'manifest_parse_error',
|
||||||
|
__( 'Could not parse manifest file.', 'maple-icons' )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $manifest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get style labels for a set.
|
||||||
|
*
|
||||||
|
* @param string $slug Icon set slug.
|
||||||
|
* @return array Array of style labels.
|
||||||
|
*/
|
||||||
|
public static function get_style_labels( $slug ) {
|
||||||
|
$set = self::get( $slug );
|
||||||
|
if ( ! $set ) {
|
||||||
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$labels = array();
|
||||||
|
foreach ( $set['styles'] as $style_slug => $style_config ) {
|
||||||
|
$labels[ $style_slug ] = $style_config['label'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $labels;
|
||||||
|
}
|
||||||
|
}
|
||||||
5
native/wordpress/maple-icons-wp/includes/index.php
Normal file
5
native/wordpress/maple-icons-wp/includes/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
5
native/wordpress/maple-icons-wp/index.php
Normal file
5
native/wordpress/maple-icons-wp/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
5
native/wordpress/maple-icons-wp/languages/index.php
Normal file
5
native/wordpress/maple-icons-wp/languages/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
230
native/wordpress/maple-icons-wp/maple-icons.php
Normal file
230
native/wordpress/maple-icons-wp/maple-icons.php
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Plugin Name: Maple Icons
|
||||||
|
* Plugin URI: https://jetrails.com/maple-icons
|
||||||
|
* Description: Insert beautiful open-source icons into your content with a Gutenberg block. Download icon sets from CDN and serve locally.
|
||||||
|
* Version: 1.0.0
|
||||||
|
* Requires at least: 6.5
|
||||||
|
* Requires PHP: 7.4
|
||||||
|
* Author: JetRails
|
||||||
|
* Author URI: https://jetrails.com
|
||||||
|
* License: GPL-2.0-or-later
|
||||||
|
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
* Text Domain: maple-icons
|
||||||
|
* Domain Path: /languages
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin constants.
|
||||||
|
*/
|
||||||
|
define( 'MI_VERSION', '1.0.0' );
|
||||||
|
define( 'MI_PLUGIN_FILE', __FILE__ );
|
||||||
|
define( 'MI_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
|
||||||
|
define( 'MI_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
|
||||||
|
define( 'MI_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );
|
||||||
|
define( 'MI_ICONS_DIR', WP_CONTENT_DIR . '/maple-icons/' );
|
||||||
|
define( 'MI_ICONS_URL', content_url( '/maple-icons/' ) );
|
||||||
|
define( 'MI_PRESETS_DIR', MI_PLUGIN_DIR . 'presets/' );
|
||||||
|
|
||||||
|
// Limits.
|
||||||
|
define( 'MI_DOWNLOAD_BATCH_SIZE', 50 );
|
||||||
|
define( 'MI_SEARCH_LIMIT', 50 );
|
||||||
|
define( 'MI_DOWNLOAD_TIMEOUT', 10 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autoloader for plugin classes.
|
||||||
|
*
|
||||||
|
* @param string $class_name The class name to load.
|
||||||
|
*/
|
||||||
|
function mi_autoloader( $class_name ) {
|
||||||
|
// Only handle our classes.
|
||||||
|
if ( strpos( $class_name, 'MI_' ) !== 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert class name to filename.
|
||||||
|
$class_file = 'class-' . strtolower( str_replace( '_', '-', $class_name ) ) . '.php';
|
||||||
|
$class_path = MI_PLUGIN_DIR . 'includes/' . $class_file;
|
||||||
|
|
||||||
|
if ( file_exists( $class_path ) ) {
|
||||||
|
require_once $class_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
spl_autoload_register( 'mi_autoloader' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin activation hook.
|
||||||
|
*/
|
||||||
|
function mi_activate() {
|
||||||
|
// Check WordPress version.
|
||||||
|
if ( version_compare( get_bloginfo( 'version' ), '6.5', '<' ) ) {
|
||||||
|
deactivate_plugins( MI_PLUGIN_BASENAME );
|
||||||
|
wp_die(
|
||||||
|
esc_html__( 'Maple Icons requires WordPress 6.5 or higher.', 'maple-icons' ),
|
||||||
|
esc_html__( 'Plugin Activation Error', 'maple-icons' ),
|
||||||
|
array( 'back_link' => true )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create icons directory if it doesn't exist.
|
||||||
|
if ( ! file_exists( MI_ICONS_DIR ) ) {
|
||||||
|
wp_mkdir_p( MI_ICONS_DIR );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initialize default settings.
|
||||||
|
$default_settings = array(
|
||||||
|
'active_set' => '',
|
||||||
|
'downloaded_sets' => array(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( false === get_option( 'maple_icons_settings' ) ) {
|
||||||
|
add_option( 'maple_icons_settings', $default_settings );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flush rewrite rules.
|
||||||
|
flush_rewrite_rules();
|
||||||
|
}
|
||||||
|
register_activation_hook( MI_PLUGIN_FILE, 'mi_activate' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plugin deactivation hook.
|
||||||
|
*/
|
||||||
|
function mi_deactivate() {
|
||||||
|
// Clean up transients.
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->query(
|
||||||
|
"DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mi_%' OR option_name LIKE '_transient_timeout_mi_%'"
|
||||||
|
);
|
||||||
|
|
||||||
|
flush_rewrite_rules();
|
||||||
|
}
|
||||||
|
register_deactivation_hook( MI_PLUGIN_FILE, 'mi_deactivate' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check WordPress version on admin init (in case WP was downgraded).
|
||||||
|
*/
|
||||||
|
function mi_check_wp_version() {
|
||||||
|
if ( version_compare( get_bloginfo( 'version' ), '6.5', '<' ) ) {
|
||||||
|
deactivate_plugins( MI_PLUGIN_BASENAME );
|
||||||
|
add_action( 'admin_notices', 'mi_wp_version_notice' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action( 'admin_init', 'mi_check_wp_version' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display admin notice for WordPress version requirement.
|
||||||
|
*/
|
||||||
|
function mi_wp_version_notice() {
|
||||||
|
echo '<div class="error"><p>';
|
||||||
|
esc_html_e( 'Maple Icons has been deactivated. It requires WordPress 6.5 or higher.', 'maple-icons' );
|
||||||
|
echo '</p></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the plugin.
|
||||||
|
*/
|
||||||
|
function mi_init() {
|
||||||
|
// Load text domain.
|
||||||
|
load_plugin_textdomain( 'maple-icons', false, dirname( MI_PLUGIN_BASENAME ) . '/languages' );
|
||||||
|
|
||||||
|
// Register the Gutenberg block.
|
||||||
|
mi_register_block();
|
||||||
|
}
|
||||||
|
add_action( 'init', 'mi_init' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the Maple Icons Gutenberg block.
|
||||||
|
*/
|
||||||
|
function mi_register_block() {
|
||||||
|
// Check if build directory exists.
|
||||||
|
$block_path = MI_PLUGIN_DIR . 'build';
|
||||||
|
|
||||||
|
if ( ! file_exists( $block_path ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
register_block_type( $block_path );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enqueue block editor assets.
|
||||||
|
*/
|
||||||
|
function mi_enqueue_block_assets() {
|
||||||
|
// Only load in block editor.
|
||||||
|
if ( ! is_admin() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$screen = get_current_screen();
|
||||||
|
if ( ! $screen || ! $screen->is_block_editor() ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Localize script data for the block editor.
|
||||||
|
$active_set = '';
|
||||||
|
$settings = get_option( 'maple_icons_settings', array() );
|
||||||
|
if ( ! empty( $settings['active_set'] ) ) {
|
||||||
|
$active_set = $settings['active_set'];
|
||||||
|
}
|
||||||
|
|
||||||
|
wp_localize_script(
|
||||||
|
'maple-icon-editor-script',
|
||||||
|
'miBlock',
|
||||||
|
array(
|
||||||
|
'ajaxUrl' => admin_url( 'admin-ajax.php' ),
|
||||||
|
'nonce' => wp_create_nonce( 'mi_block_nonce' ),
|
||||||
|
'activeSet' => $active_set,
|
||||||
|
'settingsUrl' => admin_url( 'options-general.php?page=maple-icons' ),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
add_action( 'enqueue_block_editor_assets', 'mi_enqueue_block_assets' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize admin functionality.
|
||||||
|
*/
|
||||||
|
function mi_admin_init() {
|
||||||
|
// Initialize admin page.
|
||||||
|
new MI_Admin_Page();
|
||||||
|
|
||||||
|
// Initialize AJAX handler.
|
||||||
|
new MI_Ajax_Handler();
|
||||||
|
}
|
||||||
|
add_action( 'admin_init', 'mi_admin_init' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add settings link to plugin action links.
|
||||||
|
*
|
||||||
|
* @param array $links Plugin action links.
|
||||||
|
* @return array Modified action links.
|
||||||
|
*/
|
||||||
|
function mi_add_action_links( $links ) {
|
||||||
|
$settings_link = sprintf(
|
||||||
|
'<a href="%s">%s</a>',
|
||||||
|
admin_url( 'options-general.php?page=maple-icons' ),
|
||||||
|
__( 'Settings', 'maple-icons' )
|
||||||
|
);
|
||||||
|
array_unshift( $links, $settings_link );
|
||||||
|
return $links;
|
||||||
|
}
|
||||||
|
add_filter( 'plugin_action_links_' . MI_PLUGIN_BASENAME, 'mi_add_action_links' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declare WooCommerce HPOS compatibility.
|
||||||
|
*/
|
||||||
|
function mi_declare_hpos_compatibility() {
|
||||||
|
if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
|
||||||
|
\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
|
||||||
|
'custom_order_tables',
|
||||||
|
MI_PLUGIN_FILE,
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add_action( 'before_woocommerce_init', 'mi_declare_hpos_compatibility' );
|
||||||
293
native/wordpress/maple-icons-wp/presets/feather.json
Normal file
293
native/wordpress/maple-icons-wp/presets/feather.json
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
{
|
||||||
|
"slug": "feather",
|
||||||
|
"name": "Feather",
|
||||||
|
"version": "4.29.1",
|
||||||
|
"icons": [
|
||||||
|
{"name": "activity", "tags": ["pulse", "health", "action", "motion"], "category": "health", "styles": ["icons"]},
|
||||||
|
{"name": "airplay", "tags": ["stream", "cast", "mirroring"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "alert-circle", "tags": ["warning", "alert", "danger"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "alert-octagon", "tags": ["warning", "alert", "danger", "stop"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "alert-triangle", "tags": ["warning", "alert", "danger"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "align-center", "tags": ["text", "alignment", "center"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-justify", "tags": ["text", "alignment", "justify"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-left", "tags": ["text", "alignment", "left"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-right", "tags": ["text", "alignment", "right"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "anchor", "tags": ["link", "nav", "navigation"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "aperture", "tags": ["camera", "photo", "lens"], "category": "photography", "styles": ["icons"]},
|
||||||
|
{"name": "archive", "tags": ["box", "storage", "backup"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down", "tags": ["direction", "down"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-circle", "tags": ["direction", "down", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-right", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left", "tags": ["direction", "back", "previous"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left-circle", "tags": ["direction", "back", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right", "tags": ["direction", "forward", "next"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right-circle", "tags": ["direction", "forward", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up", "tags": ["direction", "up"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-circle", "tags": ["direction", "up", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-right", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "at-sign", "tags": ["email", "mention", "at"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "award", "tags": ["achievement", "badge", "trophy"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-2", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "battery", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-charging", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "bell", "tags": ["notification", "alert", "alarm"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-off", "tags": ["notification", "mute", "silent"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bluetooth", "tags": ["wireless", "connection"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "bold", "tags": ["text", "format", "strong"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "book", "tags": ["read", "library", "education"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "book-open", "tags": ["read", "library", "education"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "bookmark", "tags": ["save", "favorite", "tag"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "box", "tags": ["package", "container", "storage"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "briefcase", "tags": ["work", "job", "business"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "calendar", "tags": ["date", "schedule", "event"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "camera", "tags": ["photo", "picture", "image"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "camera-off", "tags": ["photo", "disabled", "off"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "cast", "tags": ["stream", "broadcast", "chromecast"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "check", "tags": ["done", "complete", "success"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "check-circle", "tags": ["done", "complete", "success"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "check-square", "tags": ["done", "complete", "checkbox"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-down", "tags": ["expand", "dropdown", "arrow"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-left", "tags": ["back", "previous", "arrow"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-right", "tags": ["forward", "next", "arrow"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-up", "tags": ["collapse", "up", "arrow"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-down", "tags": ["expand", "more", "double"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-left", "tags": ["back", "previous", "double"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-right", "tags": ["forward", "next", "double"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-up", "tags": ["collapse", "less", "double"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chrome", "tags": ["browser", "google", "web"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "circle", "tags": ["shape", "dot", "record"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "clipboard", "tags": ["copy", "paste", "board"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "clock", "tags": ["time", "watch", "schedule"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "cloud", "tags": ["weather", "storage", "sky"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-drizzle", "tags": ["weather", "rain", "drizzle"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-lightning", "tags": ["weather", "storm", "thunder"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-off", "tags": ["weather", "offline", "disconnect"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-rain", "tags": ["weather", "rain", "precipitation"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-snow", "tags": ["weather", "snow", "winter"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "code", "tags": ["programming", "development", "html"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "codepen", "tags": ["brand", "code", "development"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "codesandbox", "tags": ["brand", "code", "development"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "coffee", "tags": ["drink", "cup", "cafe"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "columns", "tags": ["layout", "grid", "table"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "command", "tags": ["keyboard", "mac", "key"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "compass", "tags": ["navigation", "direction", "explore"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "copy", "tags": ["duplicate", "clone", "clipboard"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "corner-down-left", "tags": ["arrow", "return", "enter"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-down-right", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-left-down", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-left-up", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-right-down", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-right-up", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-up-left", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "corner-up-right", "tags": ["arrow", "direction"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "cpu", "tags": ["processor", "chip", "computer"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "credit-card", "tags": ["payment", "card", "money"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "crop", "tags": ["image", "edit", "resize"], "category": "editing", "styles": ["icons"]},
|
||||||
|
{"name": "crosshair", "tags": ["target", "focus", "aim"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "database", "tags": ["storage", "data", "server"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "delete", "tags": ["remove", "backspace", "erase"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "disc", "tags": ["cd", "music", "record"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "divide", "tags": ["math", "division", "split"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "divide-circle", "tags": ["math", "division", "split"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "divide-square", "tags": ["math", "division", "split"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "dollar-sign", "tags": ["money", "currency", "payment"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "download", "tags": ["save", "export", "download"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "download-cloud", "tags": ["save", "cloud", "download"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "dribbble", "tags": ["brand", "design", "social"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "droplet", "tags": ["water", "liquid", "drop"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "edit", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "edit-2", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "edit-3", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "external-link", "tags": ["link", "open", "new window"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "eye", "tags": ["view", "visible", "show"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "eye-off", "tags": ["hide", "invisible", "hidden"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "facebook", "tags": ["brand", "social", "network"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "fast-forward", "tags": ["media", "skip", "forward"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "feather", "tags": ["brand", "logo", "icon"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "figma", "tags": ["brand", "design", "tool"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "file", "tags": ["document", "page", "paper"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "file-minus", "tags": ["document", "remove", "delete"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "file-plus", "tags": ["document", "add", "new"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "file-text", "tags": ["document", "text", "content"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "film", "tags": ["video", "movie", "cinema"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "filter", "tags": ["funnel", "sort", "filter"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "flag", "tags": ["report", "mark", "country"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "folder", "tags": ["directory", "files", "organize"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "folder-minus", "tags": ["directory", "remove", "delete"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "folder-plus", "tags": ["directory", "add", "new"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "framer", "tags": ["brand", "design", "tool"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "frown", "tags": ["sad", "unhappy", "emoji"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "gift", "tags": ["present", "reward", "surprise"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "git-branch", "tags": ["version", "control", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "git-commit", "tags": ["version", "control", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "git-merge", "tags": ["version", "control", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "git-pull-request", "tags": ["version", "control", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "github", "tags": ["brand", "code", "repository"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "gitlab", "tags": ["brand", "code", "repository"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "globe", "tags": ["world", "earth", "web"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "grid", "tags": ["layout", "squares", "dashboard"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "hard-drive", "tags": ["storage", "disk", "data"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "hash", "tags": ["tag", "hashtag", "number"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "headphones", "tags": ["audio", "music", "listen"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "heart", "tags": ["love", "favorite", "like"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "help-circle", "tags": ["question", "help", "support"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "hexagon", "tags": ["shape", "polygon", "6"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "home", "tags": ["house", "main", "dashboard"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "image", "tags": ["picture", "photo", "gallery"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "inbox", "tags": ["email", "messages", "mail"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "info", "tags": ["information", "help", "about"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "instagram", "tags": ["brand", "social", "photo"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "italic", "tags": ["text", "format", "style"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "key", "tags": ["password", "security", "lock"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "layers", "tags": ["stack", "levels", "depth"], "category": "design", "styles": ["icons"]},
|
||||||
|
{"name": "layout", "tags": ["grid", "template", "design"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "life-buoy", "tags": ["help", "support", "rescue"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "link", "tags": ["url", "chain", "connect"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "link-2", "tags": ["url", "chain", "connect"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "linkedin", "tags": ["brand", "social", "professional"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "list", "tags": ["menu", "items", "bullet"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "loader", "tags": ["loading", "spinner", "wait"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "lock", "tags": ["security", "private", "password"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "log-in", "tags": ["login", "signin", "enter"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "log-out", "tags": ["logout", "signout", "exit"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "mail", "tags": ["email", "message", "envelope"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "map", "tags": ["location", "navigation", "directions"], "category": "maps", "styles": ["icons"]},
|
||||||
|
{"name": "map-pin", "tags": ["location", "marker", "place"], "category": "maps", "styles": ["icons"]},
|
||||||
|
{"name": "maximize", "tags": ["fullscreen", "expand", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "maximize-2", "tags": ["fullscreen", "expand", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "meh", "tags": ["neutral", "emoji", "face"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "menu", "tags": ["hamburger", "navigation", "bars"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "message-circle", "tags": ["chat", "comment", "conversation"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "message-square", "tags": ["chat", "comment", "conversation"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "mic", "tags": ["microphone", "audio", "record"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "mic-off", "tags": ["microphone", "mute", "silent"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "minimize", "tags": ["collapse", "shrink", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "minimize-2", "tags": ["collapse", "shrink", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "minus", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "minus-circle", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "minus-square", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "monitor", "tags": ["screen", "display", "desktop"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "moon", "tags": ["dark", "night", "theme"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "more-horizontal", "tags": ["menu", "options", "dots"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "more-vertical", "tags": ["menu", "options", "dots"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "mouse-pointer", "tags": ["cursor", "click", "select"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "move", "tags": ["drag", "reorder", "arrows"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "music", "tags": ["audio", "sound", "note"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "navigation", "tags": ["direction", "arrow", "location"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "navigation-2", "tags": ["direction", "arrow", "location"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "octagon", "tags": ["shape", "stop", "polygon"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "package", "tags": ["box", "delivery", "shipping"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "paperclip", "tags": ["attachment", "file", "clip"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "pause", "tags": ["media", "stop", "wait"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "pause-circle", "tags": ["media", "stop", "wait"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "pen-tool", "tags": ["design", "draw", "vector"], "category": "design", "styles": ["icons"]},
|
||||||
|
{"name": "percent", "tags": ["discount", "math", "percentage"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "phone", "tags": ["call", "contact", "mobile"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-call", "tags": ["call", "ringing", "incoming"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-forwarded", "tags": ["call", "forward", "redirect"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-incoming", "tags": ["call", "receive", "answer"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-missed", "tags": ["call", "missed", "unanswered"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-off", "tags": ["call", "hang up", "end"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "phone-outgoing", "tags": ["call", "dial", "outbound"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "pie-chart", "tags": ["analytics", "statistics", "data"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "play", "tags": ["media", "start", "video"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "play-circle", "tags": ["media", "start", "video"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "plus", "tags": ["add", "create", "new"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "plus-circle", "tags": ["add", "create", "new"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "plus-square", "tags": ["add", "create", "new"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "pocket", "tags": ["save", "bookmark", "read later"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "power", "tags": ["on", "off", "shutdown"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "printer", "tags": ["print", "document", "paper"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "radio", "tags": ["audio", "broadcast", "music"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "refresh-ccw", "tags": ["reload", "sync", "update"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "refresh-cw", "tags": ["reload", "sync", "update"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "repeat", "tags": ["loop", "replay", "refresh"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "rewind", "tags": ["media", "back", "previous"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "rotate-ccw", "tags": ["undo", "rotate", "turn"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "rotate-cw", "tags": ["redo", "rotate", "turn"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "rss", "tags": ["feed", "subscribe", "blog"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "save", "tags": ["disk", "floppy", "store"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "scissors", "tags": ["cut", "trim", "edit"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "search", "tags": ["find", "magnify", "look"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "send", "tags": ["message", "email", "submit"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "server", "tags": ["hosting", "database", "backend"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "settings", "tags": ["gear", "cog", "preferences"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "share", "tags": ["social", "send", "forward"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "share-2", "tags": ["social", "send", "network"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "shield", "tags": ["security", "protection", "safe"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "shield-off", "tags": ["security", "unprotected", "unsafe"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "shopping-bag", "tags": ["shop", "purchase", "buy"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "shopping-cart", "tags": ["shop", "cart", "ecommerce"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "shuffle", "tags": ["random", "mix", "music"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "sidebar", "tags": ["layout", "panel", "navigation"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "skip-back", "tags": ["media", "previous", "rewind"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "skip-forward", "tags": ["media", "next", "forward"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "slack", "tags": ["brand", "chat", "communication"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "slash", "tags": ["ban", "cancel", "disabled"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "sliders", "tags": ["settings", "controls", "adjust"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "smartphone", "tags": ["phone", "mobile", "device"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "smile", "tags": ["happy", "emoji", "face"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "speaker", "tags": ["audio", "sound", "volume"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "square", "tags": ["shape", "box", "rectangle"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "star", "tags": ["favorite", "rating", "bookmark"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "stop-circle", "tags": ["media", "stop", "end"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "sun", "tags": ["light", "day", "brightness"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "sunrise", "tags": ["morning", "dawn", "sun"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "sunset", "tags": ["evening", "dusk", "sun"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "tablet", "tags": ["device", "ipad", "screen"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "tag", "tags": ["label", "category", "price"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "target", "tags": ["goal", "aim", "focus"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "terminal", "tags": ["console", "command", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "thermometer", "tags": ["temperature", "weather", "health"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "thumbs-down", "tags": ["dislike", "bad", "negative"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "thumbs-up", "tags": ["like", "good", "positive"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "toggle-left", "tags": ["switch", "off", "disable"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "toggle-right", "tags": ["switch", "on", "enable"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "tool", "tags": ["wrench", "settings", "repair"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "trash", "tags": ["delete", "remove", "bin"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "trash-2", "tags": ["delete", "remove", "bin"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "trello", "tags": ["brand", "project", "kanban"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "trending-down", "tags": ["chart", "decrease", "analytics"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "trending-up", "tags": ["chart", "increase", "analytics"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "triangle", "tags": ["shape", "polygon", "warning"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "truck", "tags": ["delivery", "shipping", "transport"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "tv", "tags": ["television", "screen", "display"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "twitch", "tags": ["brand", "streaming", "gaming"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "twitter", "tags": ["brand", "social", "network"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "type", "tags": ["text", "font", "typography"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "umbrella", "tags": ["weather", "rain", "protection"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "underline", "tags": ["text", "format", "style"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "unlock", "tags": ["security", "open", "access"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "upload", "tags": ["export", "send", "share"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "upload-cloud", "tags": ["export", "cloud", "share"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "user", "tags": ["person", "account", "profile"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-check", "tags": ["person", "verified", "approved"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-minus", "tags": ["person", "remove", "unfriend"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-plus", "tags": ["person", "add", "invite"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-x", "tags": ["person", "delete", "remove"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "users", "tags": ["people", "team", "group"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "video", "tags": ["camera", "film", "record"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "video-off", "tags": ["camera", "disabled", "mute"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "voicemail", "tags": ["message", "audio", "phone"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "volume", "tags": ["sound", "audio", "speaker"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-1", "tags": ["sound", "audio", "low"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-2", "tags": ["sound", "audio", "high"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-x", "tags": ["mute", "silent", "no sound"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "watch", "tags": ["time", "wearable", "clock"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "wifi", "tags": ["wireless", "internet", "connection"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "wifi-off", "tags": ["wireless", "offline", "disconnect"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "wind", "tags": ["weather", "air", "breeze"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "x", "tags": ["close", "cancel", "remove"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "x-circle", "tags": ["close", "cancel", "error"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "x-octagon", "tags": ["close", "stop", "error"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "x-square", "tags": ["close", "cancel", "remove"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "youtube", "tags": ["brand", "video", "streaming"], "category": "brands", "styles": ["icons"]},
|
||||||
|
{"name": "zap", "tags": ["lightning", "power", "energy"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "zap-off", "tags": ["lightning", "disabled", "off"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "zoom-in", "tags": ["magnify", "enlarge", "plus"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "zoom-out", "tags": ["magnify", "shrink", "minus"], "category": "actions", "styles": ["icons"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
295
native/wordpress/maple-icons-wp/presets/heroicons.json
Normal file
295
native/wordpress/maple-icons-wp/presets/heroicons.json
Normal file
|
|
@ -0,0 +1,295 @@
|
||||||
|
{
|
||||||
|
"slug": "heroicons",
|
||||||
|
"name": "Heroicons",
|
||||||
|
"version": "2.1.1",
|
||||||
|
"icons": [
|
||||||
|
{"name": "academic-cap", "tags": ["education", "graduation", "school", "hat", "learning"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "adjustments-horizontal", "tags": ["settings", "controls", "sliders", "options", "configuration"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "adjustments-vertical", "tags": ["settings", "controls", "sliders", "options", "configuration"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "archive-box", "tags": ["storage", "box", "container", "archive"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "archive-box-arrow-down", "tags": ["download", "storage", "archive", "save"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "archive-box-x-mark", "tags": ["delete", "remove", "archive", "cancel"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down", "tags": ["direction", "navigation", "down", "move"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-circle", "tags": ["direction", "navigation", "down", "circle"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-left", "tags": ["direction", "navigation", "diagonal"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-on-square", "tags": ["download", "save", "import"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-on-square-stack", "tags": ["download", "save", "multiple"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-right", "tags": ["direction", "navigation", "diagonal"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-down-tray", "tags": ["download", "save", "import"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-left", "tags": ["direction", "navigation", "back", "previous"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-left-circle", "tags": ["direction", "navigation", "back", "circle"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-left-end-on-rectangle", "tags": ["logout", "exit", "leave"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-left-start-on-rectangle", "tags": ["login", "enter", "signin"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-long-down", "tags": ["direction", "navigation", "long"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-long-left", "tags": ["direction", "navigation", "long", "back"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-long-right", "tags": ["direction", "navigation", "long", "forward"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-long-up", "tags": ["direction", "navigation", "long"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-path", "tags": ["refresh", "reload", "sync", "repeat"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-path-rounded-square", "tags": ["refresh", "reload", "sync"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-right", "tags": ["direction", "navigation", "forward", "next"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-right-circle", "tags": ["direction", "navigation", "forward", "circle"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-right-end-on-rectangle", "tags": ["login", "enter", "signin"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-right-start-on-rectangle", "tags": ["logout", "exit", "leave"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-top-right-on-square", "tags": ["external", "link", "open", "new window"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-trending-down", "tags": ["chart", "decrease", "analytics", "down"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-trending-up", "tags": ["chart", "increase", "analytics", "up"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up", "tags": ["direction", "navigation", "up", "move"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-circle", "tags": ["direction", "navigation", "up", "circle"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-left", "tags": ["direction", "navigation", "diagonal"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-on-square", "tags": ["upload", "share", "export"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-on-square-stack", "tags": ["upload", "share", "multiple"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-right", "tags": ["direction", "navigation", "diagonal"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-up-tray", "tags": ["upload", "export", "share"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-uturn-down", "tags": ["undo", "return", "back"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-uturn-left", "tags": ["undo", "return", "back"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-uturn-right", "tags": ["redo", "forward"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrow-uturn-up", "tags": ["return", "back"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrows-pointing-in", "tags": ["minimize", "collapse", "shrink"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrows-pointing-out", "tags": ["maximize", "expand", "fullscreen"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrows-right-left", "tags": ["swap", "exchange", "transfer"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "arrows-up-down", "tags": ["sort", "reorder", "move"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "at-symbol", "tags": ["email", "at", "mention", "contact"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "backspace", "tags": ["delete", "remove", "erase", "keyboard"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "backward", "tags": ["media", "rewind", "previous"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "banknotes", "tags": ["money", "cash", "payment", "currency"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-2", "tags": ["menu", "hamburger", "navigation"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-3", "tags": ["menu", "hamburger", "navigation"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-3-bottom-left", "tags": ["menu", "text", "align left"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-3-bottom-right", "tags": ["menu", "text", "align right"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-3-center-left", "tags": ["menu", "text", "align"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-4", "tags": ["menu", "list", "navigation"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-arrow-down", "tags": ["sort", "descending", "order"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bars-arrow-up", "tags": ["sort", "ascending", "order"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "battery-0", "tags": ["power", "energy", "empty"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "battery-50", "tags": ["power", "energy", "half"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "battery-100", "tags": ["power", "energy", "full"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "beaker", "tags": ["science", "lab", "chemistry", "experiment"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bell", "tags": ["notification", "alert", "alarm", "ring"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bell-alert", "tags": ["notification", "alert", "alarm", "warning"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bell-slash", "tags": ["notification", "mute", "silent", "off"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bell-snooze", "tags": ["notification", "snooze", "delay", "later"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bolt", "tags": ["lightning", "power", "energy", "electric"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bolt-slash", "tags": ["lightning", "power", "off", "disabled"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "book-open", "tags": ["read", "education", "learning", "library"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bookmark", "tags": ["save", "favorite", "tag", "mark"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bookmark-slash", "tags": ["unsave", "remove", "unbookmark"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bookmark-square", "tags": ["save", "favorite", "square"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "briefcase", "tags": ["work", "job", "business", "career"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "bug-ant", "tags": ["bug", "debug", "error", "insect"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "building-library", "tags": ["library", "institution", "government"], "category": "buildings", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "building-office", "tags": ["office", "work", "business", "company"], "category": "buildings", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "building-office-2", "tags": ["office", "skyscraper", "business"], "category": "buildings", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "building-storefront", "tags": ["shop", "store", "retail", "commerce"], "category": "buildings", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cake", "tags": ["birthday", "celebration", "party", "dessert"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "calculator", "tags": ["math", "calculate", "numbers", "finance"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "calendar", "tags": ["date", "schedule", "event", "time"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "calendar-days", "tags": ["date", "schedule", "month", "planner"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "camera", "tags": ["photo", "picture", "image", "photography"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chart-bar", "tags": ["analytics", "statistics", "graph", "data"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chart-bar-square", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chart-pie", "tags": ["analytics", "statistics", "pie chart", "data"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-bottom-center", "tags": ["message", "chat", "comment", "conversation"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-bottom-center-text", "tags": ["message", "chat", "text", "comment"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-left", "tags": ["message", "chat", "comment"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-left-ellipsis", "tags": ["message", "typing", "chat"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-left-right", "tags": ["conversation", "chat", "discuss"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-oval-left", "tags": ["message", "chat", "bubble"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chat-bubble-oval-left-ellipsis", "tags": ["message", "typing", "chat"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "check", "tags": ["done", "complete", "success", "tick"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "check-badge", "tags": ["verified", "approved", "certified"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "check-circle", "tags": ["done", "complete", "success", "approved"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-double-down", "tags": ["expand", "more", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-double-left", "tags": ["previous", "back", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-double-right", "tags": ["next", "forward", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-double-up", "tags": ["collapse", "less", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-down", "tags": ["expand", "dropdown", "more"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-left", "tags": ["previous", "back", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-right", "tags": ["next", "forward", "navigation"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-up", "tags": ["collapse", "less", "close"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "chevron-up-down", "tags": ["sort", "select", "dropdown"], "category": "arrows", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "circle-stack", "tags": ["database", "storage", "data", "layers"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "clipboard", "tags": ["copy", "paste", "clipboard"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "clipboard-document", "tags": ["copy", "document", "paste"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "clipboard-document-check", "tags": ["copy", "done", "verified"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "clipboard-document-list", "tags": ["list", "tasks", "checklist"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "clock", "tags": ["time", "schedule", "watch", "hour"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cloud", "tags": ["weather", "storage", "sky", "upload"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cloud-arrow-down", "tags": ["download", "cloud", "sync"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cloud-arrow-up", "tags": ["upload", "cloud", "sync"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "code-bracket", "tags": ["code", "development", "programming"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "code-bracket-square", "tags": ["code", "development", "programming"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cog", "tags": ["settings", "gear", "configuration", "options"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cog-6-tooth", "tags": ["settings", "gear", "configuration"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cog-8-tooth", "tags": ["settings", "gear", "configuration"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "command-line", "tags": ["terminal", "console", "cli", "code"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "computer-desktop", "tags": ["desktop", "monitor", "screen", "pc"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cpu-chip", "tags": ["processor", "chip", "hardware", "computer"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "credit-card", "tags": ["payment", "card", "money", "finance"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cube", "tags": ["3d", "box", "shape", "object"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cube-transparent", "tags": ["3d", "box", "transparent"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-bangladeshi", "tags": ["money", "currency", "taka"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-dollar", "tags": ["money", "currency", "usd", "dollar"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-euro", "tags": ["money", "currency", "eur", "euro"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-pound", "tags": ["money", "currency", "gbp", "pound"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-rupee", "tags": ["money", "currency", "inr", "rupee"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "currency-yen", "tags": ["money", "currency", "jpy", "yen"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cursor-arrow-rays", "tags": ["cursor", "click", "pointer"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "cursor-arrow-ripple", "tags": ["cursor", "click", "pointer"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "device-phone-mobile", "tags": ["phone", "mobile", "smartphone"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "device-tablet", "tags": ["tablet", "ipad", "device"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document", "tags": ["file", "document", "page", "paper"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-arrow-down", "tags": ["download", "file", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-arrow-up", "tags": ["upload", "file", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-chart-bar", "tags": ["report", "analytics", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-check", "tags": ["verified", "approved", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-duplicate", "tags": ["copy", "duplicate", "clone"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-magnifying-glass", "tags": ["search", "find", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-minus", "tags": ["remove", "delete", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-plus", "tags": ["add", "new", "create", "document"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "document-text", "tags": ["file", "text", "document", "content"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "ellipsis-horizontal", "tags": ["more", "menu", "options", "dots"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "ellipsis-horizontal-circle", "tags": ["more", "menu", "options"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "ellipsis-vertical", "tags": ["more", "menu", "options", "dots"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "envelope", "tags": ["email", "mail", "message", "letter"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "envelope-open", "tags": ["email", "mail", "read", "open"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "exclamation-circle", "tags": ["warning", "alert", "error", "danger"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "exclamation-triangle", "tags": ["warning", "alert", "caution", "danger"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "eye", "tags": ["view", "visible", "show", "watch"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "eye-dropper", "tags": ["color", "picker", "dropper", "design"], "category": "design", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "eye-slash", "tags": ["hide", "invisible", "hidden", "privacy"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "face-frown", "tags": ["sad", "unhappy", "emoji", "emotion"], "category": "emoji", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "face-smile", "tags": ["happy", "smile", "emoji", "emotion"], "category": "emoji", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "film", "tags": ["video", "movie", "media", "cinema"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "finger-print", "tags": ["security", "identity", "biometric", "auth"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "fire", "tags": ["flame", "hot", "trending", "popular"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "flag", "tags": ["report", "mark", "flag", "bookmark"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "folder", "tags": ["directory", "folder", "files", "organize"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "folder-arrow-down", "tags": ["download", "folder", "save"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "folder-minus", "tags": ["remove", "folder", "delete"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "folder-open", "tags": ["open", "folder", "browse"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "folder-plus", "tags": ["add", "folder", "new", "create"], "category": "files", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "forward", "tags": ["media", "next", "skip"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "funnel", "tags": ["filter", "sort", "funnel"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "gif", "tags": ["image", "animation", "gif", "media"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "gift", "tags": ["present", "gift", "reward", "surprise"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "gift-top", "tags": ["present", "gift", "reward"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "globe-alt", "tags": ["world", "earth", "internet", "web"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "globe-americas", "tags": ["world", "earth", "americas"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "globe-asia-australia", "tags": ["world", "earth", "asia"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "globe-europe-africa", "tags": ["world", "earth", "europe"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "hand-raised", "tags": ["stop", "hand", "halt", "wait"], "category": "gestures", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "hand-thumb-down", "tags": ["dislike", "thumbs down", "bad"], "category": "gestures", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "hand-thumb-up", "tags": ["like", "thumbs up", "good", "approve"], "category": "gestures", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "hashtag", "tags": ["tag", "hashtag", "topic", "social"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "heart", "tags": ["love", "favorite", "like", "heart"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "home", "tags": ["house", "home", "main", "dashboard"], "category": "navigation", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "home-modern", "tags": ["house", "home", "building"], "category": "buildings", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "identification", "tags": ["id", "card", "identity", "badge"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "inbox", "tags": ["mail", "inbox", "messages"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "inbox-arrow-down", "tags": ["receive", "inbox", "download"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "inbox-stack", "tags": ["inbox", "messages", "stack"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "information-circle", "tags": ["info", "help", "about", "details"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "key", "tags": ["password", "security", "access", "lock"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "language", "tags": ["translate", "language", "international"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "lifebuoy", "tags": ["help", "support", "rescue", "assistance"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "light-bulb", "tags": ["idea", "light", "bulb", "creative"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "link", "tags": ["url", "link", "chain", "connect"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "list-bullet", "tags": ["list", "bullet", "items", "menu"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "lock-closed", "tags": ["security", "lock", "private", "protected"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "lock-open", "tags": ["unlock", "open", "access"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "magnifying-glass", "tags": ["search", "find", "zoom", "look"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "magnifying-glass-circle", "tags": ["search", "find", "explore"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "magnifying-glass-minus", "tags": ["zoom out", "search", "minus"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "magnifying-glass-plus", "tags": ["zoom in", "search", "plus"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "map", "tags": ["location", "map", "directions", "navigate"], "category": "maps", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "map-pin", "tags": ["location", "pin", "marker", "place"], "category": "maps", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "megaphone", "tags": ["announce", "broadcast", "marketing"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "microphone", "tags": ["audio", "voice", "record", "speak"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "minus", "tags": ["subtract", "remove", "minus", "decrease"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "minus-circle", "tags": ["remove", "delete", "minus"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "moon", "tags": ["dark", "night", "mode", "theme"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "musical-note", "tags": ["music", "audio", "sound", "note"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "newspaper", "tags": ["news", "article", "blog", "press"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "no-symbol", "tags": ["ban", "prohibited", "forbidden", "block"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "paint-brush", "tags": ["design", "art", "paint", "brush"], "category": "design", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "paper-airplane", "tags": ["send", "message", "email", "submit"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "paper-clip", "tags": ["attachment", "clip", "attach", "file"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "pause", "tags": ["media", "pause", "stop", "wait"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "pause-circle", "tags": ["media", "pause", "stop"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "pencil", "tags": ["edit", "write", "pencil", "modify"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "pencil-square", "tags": ["edit", "write", "compose"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "phone", "tags": ["call", "phone", "contact", "mobile"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "phone-arrow-down-left", "tags": ["incoming", "call", "receive"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "phone-arrow-up-right", "tags": ["outgoing", "call", "dial"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "phone-x-mark", "tags": ["hang up", "end call", "decline"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "photo", "tags": ["image", "picture", "photo", "gallery"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "play", "tags": ["media", "play", "start", "video"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "play-circle", "tags": ["media", "play", "video"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "play-pause", "tags": ["media", "toggle", "play", "pause"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "plus", "tags": ["add", "create", "new", "plus"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "plus-circle", "tags": ["add", "create", "new"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "power", "tags": ["on", "off", "power", "shutdown"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "presentation-chart-bar", "tags": ["presentation", "chart", "analytics"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "presentation-chart-line", "tags": ["presentation", "chart", "analytics"], "category": "charts", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "printer", "tags": ["print", "printer", "document"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "puzzle-piece", "tags": ["plugin", "extension", "puzzle", "addon"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "qr-code", "tags": ["qr", "code", "scan", "barcode"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "question-mark-circle", "tags": ["help", "question", "support", "faq"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "queue-list", "tags": ["list", "queue", "playlist"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "radio", "tags": ["radio", "audio", "broadcast"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "receipt-percent", "tags": ["discount", "sale", "coupon"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "receipt-refund", "tags": ["refund", "return", "money back"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "rectangle-group", "tags": ["layout", "grid", "components"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "rectangle-stack", "tags": ["layers", "stack", "cards"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "rocket-launch", "tags": ["launch", "startup", "rocket", "deploy"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "rss", "tags": ["feed", "rss", "subscribe", "blog"], "category": "communication", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "scale", "tags": ["balance", "justice", "legal", "weight"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "scissors", "tags": ["cut", "scissors", "trim", "edit"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "server", "tags": ["server", "hosting", "database", "backend"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "server-stack", "tags": ["servers", "hosting", "infrastructure"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "share", "tags": ["share", "send", "social", "forward"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "shield-check", "tags": ["security", "protected", "verified", "safe"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "shield-exclamation", "tags": ["security", "warning", "alert"], "category": "security", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "shopping-bag", "tags": ["shop", "bag", "purchase", "buy"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "shopping-cart", "tags": ["cart", "shop", "ecommerce", "buy"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "signal", "tags": ["wifi", "signal", "connection", "network"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "signal-slash", "tags": ["no signal", "offline", "disconnected"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "sparkles", "tags": ["magic", "sparkle", "new", "ai"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "speaker-wave", "tags": ["audio", "sound", "volume", "speaker"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "speaker-x-mark", "tags": ["mute", "silent", "no sound"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "square-2-stack", "tags": ["copy", "duplicate", "stack"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "square-3-stack-3d", "tags": ["layers", "3d", "stack"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "squares-2x2", "tags": ["grid", "layout", "dashboard"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "squares-plus", "tags": ["add", "widget", "new"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "star", "tags": ["favorite", "star", "rating", "bookmark"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "stop", "tags": ["media", "stop", "end"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "stop-circle", "tags": ["media", "stop", "end"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "sun", "tags": ["light", "day", "bright", "theme"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "swatch", "tags": ["color", "palette", "design", "theme"], "category": "design", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "table-cells", "tags": ["table", "grid", "spreadsheet", "data"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "tag", "tags": ["label", "tag", "category", "price"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "ticket", "tags": ["ticket", "event", "pass", "coupon"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "trash", "tags": ["delete", "remove", "trash", "bin"], "category": "actions", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "trophy", "tags": ["award", "winner", "achievement", "prize"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "truck", "tags": ["delivery", "shipping", "truck", "transport"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "tv", "tags": ["television", "tv", "screen", "display"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "user", "tags": ["person", "user", "account", "profile"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "user-circle", "tags": ["avatar", "profile", "account"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "user-group", "tags": ["team", "group", "users", "people"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "user-minus", "tags": ["remove user", "unfriend", "delete"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "user-plus", "tags": ["add user", "invite", "new user"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "users", "tags": ["people", "team", "community"], "category": "users", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "variable", "tags": ["code", "variable", "math", "programming"], "category": "development", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "video-camera", "tags": ["video", "camera", "record", "film"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "video-camera-slash", "tags": ["video off", "camera off", "mute"], "category": "media", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "view-columns", "tags": ["columns", "layout", "grid"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "view-finder-circle", "tags": ["focus", "target", "aim"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "wallet", "tags": ["money", "payment", "wallet", "finance"], "category": "commerce", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "wifi", "tags": ["wireless", "internet", "connection", "network"], "category": "devices", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "window", "tags": ["browser", "window", "app"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "wrench", "tags": ["tools", "settings", "repair", "fix"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "wrench-screwdriver", "tags": ["tools", "settings", "repair"], "category": "objects", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "x-circle", "tags": ["close", "cancel", "remove", "delete"], "category": "ui", "styles": ["outline", "solid", "mini"]},
|
||||||
|
{"name": "x-mark", "tags": ["close", "cancel", "remove", "x"], "category": "ui", "styles": ["outline", "solid", "mini"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
5
native/wordpress/maple-icons-wp/presets/index.php
Normal file
5
native/wordpress/maple-icons-wp/presets/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
357
native/wordpress/maple-icons-wp/presets/lucide.json
Normal file
357
native/wordpress/maple-icons-wp/presets/lucide.json
Normal file
|
|
@ -0,0 +1,357 @@
|
||||||
|
{
|
||||||
|
"slug": "lucide",
|
||||||
|
"name": "Lucide",
|
||||||
|
"version": "0.303.0",
|
||||||
|
"icons": [
|
||||||
|
{"name": "accessibility", "tags": ["wheelchair", "disabled", "handicap"], "category": "accessibility", "styles": ["icons"]},
|
||||||
|
{"name": "activity", "tags": ["pulse", "health", "heart"], "category": "medical", "styles": ["icons"]},
|
||||||
|
{"name": "air-vent", "tags": ["ventilation", "hvac", "climate"], "category": "home", "styles": ["icons"]},
|
||||||
|
{"name": "airplay", "tags": ["stream", "cast", "screen"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "alarm-clock", "tags": ["time", "wake", "alert"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "album", "tags": ["music", "photos", "collection"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "alert-circle", "tags": ["warning", "error", "danger"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "alert-octagon", "tags": ["warning", "stop", "error"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "alert-triangle", "tags": ["warning", "caution", "error"], "category": "alerts", "styles": ["icons"]},
|
||||||
|
{"name": "align-center", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-center-horizontal", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-center-vertical", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-end-horizontal", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-end-vertical", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-distribute-center", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-distribute-end", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-distribute-start", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-justify-center", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-justify-end", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-justify-start", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-space-around", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-horizontal-space-between", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-justify", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-left", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-right", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "align-start-horizontal", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-start-vertical", "tags": ["layout", "distribute"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-distribute-center", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-distribute-end", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-distribute-start", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-justify-center", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-justify-end", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-justify-start", "tags": ["layout", "justify"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-space-around", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "align-vertical-space-between", "tags": ["layout", "spacing"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "anchor", "tags": ["link", "marine", "ship"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "angry", "tags": ["emoji", "emotion", "face"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "annoyed", "tags": ["emoji", "emotion", "face"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "aperture", "tags": ["camera", "lens", "photo"], "category": "photography", "styles": ["icons"]},
|
||||||
|
{"name": "app-window", "tags": ["application", "program", "software"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "apple", "tags": ["fruit", "food", "healthy"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "archive", "tags": ["box", "storage", "files"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "archive-restore", "tags": ["unarchive", "restore", "files"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "archive-x", "tags": ["delete", "remove", "files"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "armchair", "tags": ["furniture", "seat", "chair"], "category": "furniture", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-down", "tags": ["direction", "down", "navigation"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-down-dash", "tags": ["direction", "down", "end"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-left", "tags": ["direction", "left", "back"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-left-dash", "tags": ["direction", "left", "start"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-right", "tags": ["direction", "right", "forward"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-right-dash", "tags": ["direction", "right", "end"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-up", "tags": ["direction", "up", "navigation"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-big-up-dash", "tags": ["direction", "up", "start"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down", "tags": ["direction", "down"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-circle", "tags": ["direction", "down", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-from-line", "tags": ["download", "export"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-left-from-circle", "tags": ["direction", "exit"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-right", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-right-from-circle", "tags": ["direction", "exit"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-to-dot", "tags": ["direction", "target"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-down-to-line", "tags": ["download", "bottom"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left", "tags": ["direction", "back", "previous"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left-circle", "tags": ["direction", "back", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left-from-line", "tags": ["exit", "leave"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left-right", "tags": ["swap", "exchange", "horizontal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-left-to-line", "tags": ["start", "beginning"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right", "tags": ["direction", "forward", "next"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right-circle", "tags": ["direction", "forward", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right-from-line", "tags": ["exit", "export"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-right-to-line", "tags": ["end", "finish"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up", "tags": ["direction", "up"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-circle", "tags": ["direction", "up", "circle"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-down", "tags": ["sort", "reorder", "vertical"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-from-dot", "tags": ["direction", "source"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-from-line", "tags": ["upload", "export"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-right", "tags": ["direction", "diagonal", "external"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "arrow-up-to-line", "tags": ["upload", "top"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "asterisk", "tags": ["star", "required", "note"], "category": "symbols", "styles": ["icons"]},
|
||||||
|
{"name": "at-sign", "tags": ["email", "mention", "at"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "atom", "tags": ["science", "physics", "nuclear"], "category": "science", "styles": ["icons"]},
|
||||||
|
{"name": "award", "tags": ["achievement", "badge", "medal"], "category": "awards", "styles": ["icons"]},
|
||||||
|
{"name": "axe", "tags": ["tool", "chop", "wood"], "category": "tools", "styles": ["icons"]},
|
||||||
|
{"name": "baby", "tags": ["child", "infant", "kid"], "category": "people", "styles": ["icons"]},
|
||||||
|
{"name": "backpack", "tags": ["bag", "school", "travel"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "badge", "tags": ["label", "tag", "verified"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-alert", "tags": ["warning", "notification"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-check", "tags": ["verified", "approved", "done"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-dollar-sign", "tags": ["money", "price", "cost"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "badge-help", "tags": ["question", "support", "info"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-info", "tags": ["information", "details", "about"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-minus", "tags": ["remove", "subtract", "delete"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-percent", "tags": ["discount", "sale", "offer"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "badge-plus", "tags": ["add", "new", "create"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "badge-x", "tags": ["remove", "delete", "cancel"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "baggage-claim", "tags": ["airport", "luggage", "travel"], "category": "travel", "styles": ["icons"]},
|
||||||
|
{"name": "ban", "tags": ["block", "forbidden", "prohibited"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "banana", "tags": ["fruit", "food", "healthy"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "banknote", "tags": ["money", "cash", "currency"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-2", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-3", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-4", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-big", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-horizontal", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "bar-chart-horizontal-big", "tags": ["analytics", "statistics", "graph"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "battery", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-charging", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-full", "tags": ["power", "energy", "full"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-low", "tags": ["power", "energy", "low"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-medium", "tags": ["power", "energy", "half"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "battery-warning", "tags": ["power", "energy", "alert"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "beaker", "tags": ["science", "lab", "chemistry"], "category": "science", "styles": ["icons"]},
|
||||||
|
{"name": "bean", "tags": ["food", "vegetable", "seed"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "bean-off", "tags": ["food", "allergy", "no"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "bed", "tags": ["sleep", "hotel", "rest"], "category": "furniture", "styles": ["icons"]},
|
||||||
|
{"name": "bed-double", "tags": ["sleep", "hotel", "bedroom"], "category": "furniture", "styles": ["icons"]},
|
||||||
|
{"name": "bed-single", "tags": ["sleep", "hotel", "bedroom"], "category": "furniture", "styles": ["icons"]},
|
||||||
|
{"name": "beer", "tags": ["drink", "alcohol", "bar"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "bell", "tags": ["notification", "alert", "alarm"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-dot", "tags": ["notification", "alert", "new"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-minus", "tags": ["notification", "remove", "mute"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-off", "tags": ["notification", "mute", "silent"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-plus", "tags": ["notification", "add", "subscribe"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bell-ring", "tags": ["notification", "alert", "ringing"], "category": "notifications", "styles": ["icons"]},
|
||||||
|
{"name": "bike", "tags": ["bicycle", "cycling", "transport"], "category": "transportation", "styles": ["icons"]},
|
||||||
|
{"name": "binary", "tags": ["code", "programming", "data"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "bluetooth", "tags": ["wireless", "connection", "device"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "bluetooth-connected", "tags": ["wireless", "paired", "device"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "bluetooth-off", "tags": ["wireless", "disabled", "device"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "bluetooth-searching", "tags": ["wireless", "scanning", "device"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "bold", "tags": ["text", "format", "strong"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "bomb", "tags": ["explosive", "danger", "warning"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "bone", "tags": ["skeleton", "body", "medical"], "category": "medical", "styles": ["icons"]},
|
||||||
|
{"name": "book", "tags": ["read", "library", "education"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-copy", "tags": ["duplicate", "clone", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-down", "tags": ["download", "save", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-key", "tags": ["password", "secret", "secure"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-lock", "tags": ["private", "secure", "protected"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-marked", "tags": ["bookmark", "saved", "reading"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-minus", "tags": ["remove", "delete", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-open", "tags": ["read", "library", "education"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-open-check", "tags": ["read", "complete", "done"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-plus", "tags": ["add", "new", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-up", "tags": ["upload", "export", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "book-x", "tags": ["remove", "cancel", "library"], "category": "education", "styles": ["icons"]},
|
||||||
|
{"name": "bookmark", "tags": ["save", "favorite", "tag"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "bookmark-minus", "tags": ["remove", "unsave", "tag"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "bookmark-plus", "tags": ["add", "save", "tag"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "bot", "tags": ["robot", "ai", "automation"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "box", "tags": ["package", "container", "storage"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "box-select", "tags": ["selection", "area", "region"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "boxes", "tags": ["packages", "inventory", "storage"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "braces", "tags": ["code", "curly", "programming"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "brackets", "tags": ["code", "array", "programming"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "brain", "tags": ["mind", "thinking", "intelligence"], "category": "medical", "styles": ["icons"]},
|
||||||
|
{"name": "briefcase", "tags": ["work", "job", "business"], "category": "business", "styles": ["icons"]},
|
||||||
|
{"name": "brush", "tags": ["paint", "art", "design"], "category": "design", "styles": ["icons"]},
|
||||||
|
{"name": "bug", "tags": ["insect", "error", "debug"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "building", "tags": ["office", "company", "business"], "category": "buildings", "styles": ["icons"]},
|
||||||
|
{"name": "building-2", "tags": ["office", "company", "business"], "category": "buildings", "styles": ["icons"]},
|
||||||
|
{"name": "bus", "tags": ["transport", "vehicle", "travel"], "category": "transportation", "styles": ["icons"]},
|
||||||
|
{"name": "cable", "tags": ["wire", "connection", "plug"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "cake", "tags": ["birthday", "celebration", "party"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "calculator", "tags": ["math", "calculate", "numbers"], "category": "tools", "styles": ["icons"]},
|
||||||
|
{"name": "calendar", "tags": ["date", "schedule", "event"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "calendar-check", "tags": ["date", "done", "confirmed"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "calendar-clock", "tags": ["date", "time", "schedule"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "calendar-days", "tags": ["date", "month", "schedule"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "camera", "tags": ["photo", "picture", "image"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "camera-off", "tags": ["photo", "disabled", "no"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "car", "tags": ["vehicle", "transport", "drive"], "category": "transportation", "styles": ["icons"]},
|
||||||
|
{"name": "check", "tags": ["done", "complete", "success"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "check-check", "tags": ["done", "verified", "double"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "check-circle", "tags": ["done", "complete", "success"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "check-circle-2", "tags": ["done", "complete", "success"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "check-square", "tags": ["done", "checkbox", "task"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-down", "tags": ["arrow", "expand", "dropdown"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-left", "tags": ["arrow", "back", "previous"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-right", "tags": ["arrow", "forward", "next"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevron-up", "tags": ["arrow", "collapse", "up"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-down", "tags": ["arrows", "expand", "more"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-left", "tags": ["arrows", "back", "first"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-right", "tags": ["arrows", "forward", "last"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "chevrons-up", "tags": ["arrows", "collapse", "less"], "category": "arrows", "styles": ["icons"]},
|
||||||
|
{"name": "circle", "tags": ["shape", "dot", "record"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "clipboard", "tags": ["copy", "paste", "board"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "clipboard-check", "tags": ["done", "verified", "complete"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "clipboard-copy", "tags": ["copy", "duplicate", "paste"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "clipboard-list", "tags": ["tasks", "checklist", "todo"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "clock", "tags": ["time", "watch", "schedule"], "category": "time", "styles": ["icons"]},
|
||||||
|
{"name": "cloud", "tags": ["weather", "storage", "sky"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-download", "tags": ["download", "save", "sync"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-off", "tags": ["offline", "disconnect", "no"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "cloud-upload", "tags": ["upload", "sync", "backup"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "code", "tags": ["programming", "html", "development"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "code-2", "tags": ["programming", "brackets", "development"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "coffee", "tags": ["drink", "cup", "cafe"], "category": "food", "styles": ["icons"]},
|
||||||
|
{"name": "cog", "tags": ["settings", "gear", "config"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "command", "tags": ["keyboard", "mac", "shortcut"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "compass", "tags": ["navigation", "direction", "explore"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "copy", "tags": ["duplicate", "clipboard", "clone"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "credit-card", "tags": ["payment", "card", "money"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "crop", "tags": ["image", "edit", "resize"], "category": "editing", "styles": ["icons"]},
|
||||||
|
{"name": "database", "tags": ["storage", "data", "server"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "delete", "tags": ["remove", "trash", "erase"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "download", "tags": ["save", "export", "arrow"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "download-cloud", "tags": ["save", "sync", "backup"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "edit", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "edit-2", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "edit-3", "tags": ["pencil", "write", "modify"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "external-link", "tags": ["link", "open", "new window"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "eye", "tags": ["view", "visible", "show"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "eye-off", "tags": ["hide", "invisible", "hidden"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "file", "tags": ["document", "page", "paper"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "file-plus", "tags": ["document", "add", "new"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "file-text", "tags": ["document", "text", "content"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "filter", "tags": ["funnel", "sort", "search"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "flag", "tags": ["report", "mark", "country"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "folder", "tags": ["directory", "files", "organize"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "folder-open", "tags": ["directory", "browse", "explore"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "folder-plus", "tags": ["directory", "add", "new"], "category": "files", "styles": ["icons"]},
|
||||||
|
{"name": "gift", "tags": ["present", "reward", "surprise"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "globe", "tags": ["world", "earth", "web"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "grid", "tags": ["layout", "squares", "dashboard"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "hash", "tags": ["tag", "hashtag", "number"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "heart", "tags": ["love", "favorite", "like"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "help-circle", "tags": ["question", "help", "support"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "home", "tags": ["house", "main", "dashboard"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "image", "tags": ["picture", "photo", "gallery"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "inbox", "tags": ["email", "messages", "mail"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "info", "tags": ["information", "help", "about"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "key", "tags": ["password", "security", "lock"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "layers", "tags": ["stack", "levels", "depth"], "category": "design", "styles": ["icons"]},
|
||||||
|
{"name": "layout", "tags": ["grid", "template", "design"], "category": "layout", "styles": ["icons"]},
|
||||||
|
{"name": "link", "tags": ["url", "chain", "connect"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "list", "tags": ["menu", "items", "bullet"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "loader", "tags": ["loading", "spinner", "wait"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "loader-2", "tags": ["loading", "spinner", "wait"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "lock", "tags": ["security", "private", "password"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "log-in", "tags": ["login", "signin", "enter"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "log-out", "tags": ["logout", "signout", "exit"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "mail", "tags": ["email", "message", "envelope"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "map", "tags": ["location", "navigation", "directions"], "category": "maps", "styles": ["icons"]},
|
||||||
|
{"name": "map-pin", "tags": ["location", "marker", "place"], "category": "maps", "styles": ["icons"]},
|
||||||
|
{"name": "maximize", "tags": ["fullscreen", "expand", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "maximize-2", "tags": ["fullscreen", "expand", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "menu", "tags": ["hamburger", "navigation", "bars"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "message-circle", "tags": ["chat", "comment", "conversation"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "message-square", "tags": ["chat", "comment", "conversation"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "mic", "tags": ["microphone", "audio", "record"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "mic-off", "tags": ["microphone", "mute", "silent"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "minimize", "tags": ["collapse", "shrink", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "minimize-2", "tags": ["collapse", "shrink", "resize"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "minus", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "minus-circle", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "monitor", "tags": ["screen", "display", "desktop"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "moon", "tags": ["dark", "night", "theme"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "more-horizontal", "tags": ["menu", "options", "dots"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "more-vertical", "tags": ["menu", "options", "dots"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "move", "tags": ["drag", "reorder", "arrows"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "music", "tags": ["audio", "sound", "note"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "navigation", "tags": ["direction", "arrow", "location"], "category": "navigation", "styles": ["icons"]},
|
||||||
|
{"name": "package", "tags": ["box", "delivery", "shipping"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "paperclip", "tags": ["attachment", "file", "clip"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "pause", "tags": ["media", "stop", "wait"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "pencil", "tags": ["edit", "write", "draw"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "phone", "tags": ["call", "contact", "mobile"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "pie-chart", "tags": ["analytics", "statistics", "data"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "play", "tags": ["media", "start", "video"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "play-circle", "tags": ["media", "start", "video"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "plus", "tags": ["add", "create", "new"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "plus-circle", "tags": ["add", "create", "new"], "category": "math", "styles": ["icons"]},
|
||||||
|
{"name": "power", "tags": ["on", "off", "shutdown"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "printer", "tags": ["print", "document", "paper"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "refresh-ccw", "tags": ["reload", "sync", "update"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "refresh-cw", "tags": ["reload", "sync", "update"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "repeat", "tags": ["loop", "replay", "refresh"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "rotate-ccw", "tags": ["undo", "rotate", "turn"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "rotate-cw", "tags": ["redo", "rotate", "turn"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "rss", "tags": ["feed", "subscribe", "blog"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "save", "tags": ["disk", "floppy", "store"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "scissors", "tags": ["cut", "trim", "edit"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "search", "tags": ["find", "magnify", "look"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "send", "tags": ["message", "email", "submit"], "category": "communication", "styles": ["icons"]},
|
||||||
|
{"name": "server", "tags": ["hosting", "database", "backend"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "settings", "tags": ["gear", "cog", "preferences"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "settings-2", "tags": ["sliders", "controls", "adjust"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "share", "tags": ["social", "send", "forward"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "share-2", "tags": ["social", "send", "network"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "shield", "tags": ["security", "protection", "safe"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "shopping-bag", "tags": ["shop", "purchase", "buy"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "shopping-cart", "tags": ["shop", "cart", "ecommerce"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "shuffle", "tags": ["random", "mix", "music"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "skip-back", "tags": ["media", "previous", "rewind"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "skip-forward", "tags": ["media", "next", "forward"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "slash", "tags": ["ban", "cancel", "disabled"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "sliders", "tags": ["settings", "controls", "adjust"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "smartphone", "tags": ["phone", "mobile", "device"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "smile", "tags": ["happy", "emoji", "face"], "category": "emoji", "styles": ["icons"]},
|
||||||
|
{"name": "sparkles", "tags": ["magic", "new", "ai"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "speaker", "tags": ["audio", "sound", "volume"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "star", "tags": ["favorite", "rating", "bookmark"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "stop-circle", "tags": ["media", "stop", "end"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "sun", "tags": ["light", "day", "brightness"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "table", "tags": ["data", "grid", "spreadsheet"], "category": "data", "styles": ["icons"]},
|
||||||
|
{"name": "tablet", "tags": ["device", "ipad", "screen"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "tag", "tags": ["label", "category", "price"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "target", "tags": ["goal", "aim", "focus"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "terminal", "tags": ["console", "command", "code"], "category": "development", "styles": ["icons"]},
|
||||||
|
{"name": "thumbs-down", "tags": ["dislike", "bad", "negative"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "thumbs-up", "tags": ["like", "good", "positive"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "toggle-left", "tags": ["switch", "off", "disable"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "toggle-right", "tags": ["switch", "on", "enable"], "category": "ui", "styles": ["icons"]},
|
||||||
|
{"name": "trash", "tags": ["delete", "remove", "bin"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "trash-2", "tags": ["delete", "remove", "bin"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "trending-down", "tags": ["chart", "decrease", "analytics"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "trending-up", "tags": ["chart", "increase", "analytics"], "category": "charts", "styles": ["icons"]},
|
||||||
|
{"name": "triangle", "tags": ["shape", "polygon", "warning"], "category": "shapes", "styles": ["icons"]},
|
||||||
|
{"name": "truck", "tags": ["delivery", "shipping", "transport"], "category": "transportation", "styles": ["icons"]},
|
||||||
|
{"name": "tv", "tags": ["television", "screen", "display"], "category": "devices", "styles": ["icons"]},
|
||||||
|
{"name": "type", "tags": ["text", "font", "typography"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "umbrella", "tags": ["weather", "rain", "protection"], "category": "weather", "styles": ["icons"]},
|
||||||
|
{"name": "underline", "tags": ["text", "format", "style"], "category": "text", "styles": ["icons"]},
|
||||||
|
{"name": "undo", "tags": ["back", "reverse", "history"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "unlock", "tags": ["security", "open", "access"], "category": "security", "styles": ["icons"]},
|
||||||
|
{"name": "upload", "tags": ["export", "send", "share"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "upload-cloud", "tags": ["export", "sync", "backup"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "user", "tags": ["person", "account", "profile"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-check", "tags": ["person", "verified", "approved"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-minus", "tags": ["person", "remove", "unfriend"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-plus", "tags": ["person", "add", "invite"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "user-x", "tags": ["person", "delete", "remove"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "users", "tags": ["people", "team", "group"], "category": "users", "styles": ["icons"]},
|
||||||
|
{"name": "video", "tags": ["camera", "film", "record"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "video-off", "tags": ["camera", "disabled", "mute"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume", "tags": ["sound", "audio", "speaker"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-1", "tags": ["sound", "audio", "low"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-2", "tags": ["sound", "audio", "high"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "volume-x", "tags": ["mute", "silent", "no sound"], "category": "media", "styles": ["icons"]},
|
||||||
|
{"name": "wallet", "tags": ["money", "payment", "finance"], "category": "commerce", "styles": ["icons"]},
|
||||||
|
{"name": "wifi", "tags": ["wireless", "internet", "connection"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "wifi-off", "tags": ["wireless", "offline", "disconnect"], "category": "connectivity", "styles": ["icons"]},
|
||||||
|
{"name": "x", "tags": ["close", "cancel", "remove"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "x-circle", "tags": ["close", "cancel", "error"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "zap", "tags": ["lightning", "power", "energy"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "zap-off", "tags": ["lightning", "disabled", "off"], "category": "objects", "styles": ["icons"]},
|
||||||
|
{"name": "zoom-in", "tags": ["magnify", "enlarge", "plus"], "category": "actions", "styles": ["icons"]},
|
||||||
|
{"name": "zoom-out", "tags": ["magnify", "shrink", "minus"], "category": "actions", "styles": ["icons"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
455
native/wordpress/maple-icons-wp/presets/material.json
Normal file
455
native/wordpress/maple-icons-wp/presets/material.json
Normal file
|
|
@ -0,0 +1,455 @@
|
||||||
|
{
|
||||||
|
"name": "Material Symbols",
|
||||||
|
"slug": "material",
|
||||||
|
"version": "latest",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"url": "https://fonts.google.com/icons",
|
||||||
|
"styles": ["outlined", "rounded", "sharp"],
|
||||||
|
"defaultStyle": "outlined",
|
||||||
|
"viewBox": "0 0 24 24",
|
||||||
|
"cdn": {
|
||||||
|
"base": "https://cdn.jsdelivr.net/npm/@material-symbols/svg-400@0.14.5",
|
||||||
|
"pattern": "{style}/{name}.svg"
|
||||||
|
},
|
||||||
|
"icons": [
|
||||||
|
{"name": "home", "tags": ["house", "residence", "building"]},
|
||||||
|
{"name": "search", "tags": ["find", "magnify", "lookup"]},
|
||||||
|
{"name": "settings", "tags": ["cog", "gear", "preferences", "config"]},
|
||||||
|
{"name": "menu", "tags": ["hamburger", "navigation", "bars"]},
|
||||||
|
{"name": "close", "tags": ["x", "dismiss", "cancel", "remove"]},
|
||||||
|
{"name": "check", "tags": ["tick", "done", "complete", "success"]},
|
||||||
|
{"name": "add", "tags": ["plus", "new", "create"]},
|
||||||
|
{"name": "remove", "tags": ["minus", "subtract", "delete"]},
|
||||||
|
{"name": "edit", "tags": ["pencil", "modify", "change"]},
|
||||||
|
{"name": "delete", "tags": ["trash", "bin", "remove"]},
|
||||||
|
{"name": "favorite", "tags": ["heart", "love", "like"]},
|
||||||
|
{"name": "star", "tags": ["rating", "bookmark", "featured"]},
|
||||||
|
{"name": "share", "tags": ["social", "send", "distribute"]},
|
||||||
|
{"name": "person", "tags": ["user", "profile", "account"]},
|
||||||
|
{"name": "people", "tags": ["users", "group", "team"]},
|
||||||
|
{"name": "mail", "tags": ["email", "envelope", "message"]},
|
||||||
|
{"name": "call", "tags": ["phone", "telephone", "contact"]},
|
||||||
|
{"name": "chat", "tags": ["message", "conversation", "bubble"]},
|
||||||
|
{"name": "notifications", "tags": ["bell", "alert", "alarm"]},
|
||||||
|
{"name": "calendar_today", "tags": ["date", "schedule", "event"]},
|
||||||
|
{"name": "schedule", "tags": ["time", "clock", "watch"]},
|
||||||
|
{"name": "location_on", "tags": ["pin", "map", "place", "marker"]},
|
||||||
|
{"name": "directions", "tags": ["navigate", "route", "arrow"]},
|
||||||
|
{"name": "photo", "tags": ["image", "picture", "gallery"]},
|
||||||
|
{"name": "camera", "tags": ["photo", "capture", "snapshot"]},
|
||||||
|
{"name": "videocam", "tags": ["video", "movie", "record"]},
|
||||||
|
{"name": "mic", "tags": ["microphone", "audio", "voice"]},
|
||||||
|
{"name": "volume_up", "tags": ["sound", "speaker", "audio"]},
|
||||||
|
{"name": "volume_off", "tags": ["mute", "silent", "quiet"]},
|
||||||
|
{"name": "play_arrow", "tags": ["start", "begin", "media"]},
|
||||||
|
{"name": "pause", "tags": ["stop", "hold", "media"]},
|
||||||
|
{"name": "stop", "tags": ["end", "halt", "media"]},
|
||||||
|
{"name": "skip_next", "tags": ["forward", "next", "media"]},
|
||||||
|
{"name": "skip_previous", "tags": ["back", "previous", "media"]},
|
||||||
|
{"name": "replay", "tags": ["repeat", "refresh", "again"]},
|
||||||
|
{"name": "shuffle", "tags": ["random", "mix", "media"]},
|
||||||
|
{"name": "folder", "tags": ["directory", "file", "storage"]},
|
||||||
|
{"name": "folder_open", "tags": ["directory", "file", "open"]},
|
||||||
|
{"name": "file_copy", "tags": ["document", "duplicate", "clone"]},
|
||||||
|
{"name": "attach_file", "tags": ["attachment", "paperclip", "document"]},
|
||||||
|
{"name": "cloud", "tags": ["weather", "storage", "upload"]},
|
||||||
|
{"name": "cloud_upload", "tags": ["upload", "save", "storage"]},
|
||||||
|
{"name": "cloud_download", "tags": ["download", "save", "storage"]},
|
||||||
|
{"name": "download", "tags": ["save", "arrow", "get"]},
|
||||||
|
{"name": "upload", "tags": ["send", "arrow", "put"]},
|
||||||
|
{"name": "sync", "tags": ["refresh", "update", "reload"]},
|
||||||
|
{"name": "refresh", "tags": ["reload", "update", "sync"]},
|
||||||
|
{"name": "lock", "tags": ["security", "password", "secure"]},
|
||||||
|
{"name": "lock_open", "tags": ["unlock", "open", "access"]},
|
||||||
|
{"name": "visibility", "tags": ["eye", "view", "show"]},
|
||||||
|
{"name": "visibility_off", "tags": ["eye", "hide", "hidden"]},
|
||||||
|
{"name": "key", "tags": ["password", "access", "security"]},
|
||||||
|
{"name": "shield", "tags": ["security", "protect", "safe"]},
|
||||||
|
{"name": "verified", "tags": ["check", "approved", "trusted"]},
|
||||||
|
{"name": "warning", "tags": ["alert", "caution", "danger"]},
|
||||||
|
{"name": "error", "tags": ["alert", "problem", "issue"]},
|
||||||
|
{"name": "info", "tags": ["information", "help", "about"]},
|
||||||
|
{"name": "help", "tags": ["question", "support", "info"]},
|
||||||
|
{"name": "lightbulb", "tags": ["idea", "tip", "suggestion"]},
|
||||||
|
{"name": "thumb_up", "tags": ["like", "approve", "good"]},
|
||||||
|
{"name": "thumb_down", "tags": ["dislike", "reject", "bad"]},
|
||||||
|
{"name": "mood", "tags": ["emoji", "face", "happy"]},
|
||||||
|
{"name": "sentiment_satisfied", "tags": ["happy", "smile", "positive"]},
|
||||||
|
{"name": "sentiment_dissatisfied", "tags": ["sad", "unhappy", "negative"]},
|
||||||
|
{"name": "shopping_cart", "tags": ["cart", "buy", "purchase", "ecommerce"]},
|
||||||
|
{"name": "shopping_bag", "tags": ["bag", "buy", "purchase", "retail"]},
|
||||||
|
{"name": "store", "tags": ["shop", "retail", "business"]},
|
||||||
|
{"name": "payments", "tags": ["money", "card", "credit"]},
|
||||||
|
{"name": "credit_card", "tags": ["payment", "money", "bank"]},
|
||||||
|
{"name": "account_balance", "tags": ["bank", "finance", "money"]},
|
||||||
|
{"name": "receipt", "tags": ["invoice", "bill", "payment"]},
|
||||||
|
{"name": "local_shipping", "tags": ["delivery", "truck", "shipping"]},
|
||||||
|
{"name": "inventory", "tags": ["stock", "warehouse", "storage"]},
|
||||||
|
{"name": "work", "tags": ["briefcase", "job", "business"]},
|
||||||
|
{"name": "business", "tags": ["building", "company", "office"]},
|
||||||
|
{"name": "apartment", "tags": ["building", "home", "residence"]},
|
||||||
|
{"name": "school", "tags": ["education", "learning", "building"]},
|
||||||
|
{"name": "restaurant", "tags": ["food", "dining", "eat"]},
|
||||||
|
{"name": "local_cafe", "tags": ["coffee", "drink", "cup"]},
|
||||||
|
{"name": "local_bar", "tags": ["drink", "cocktail", "alcohol"]},
|
||||||
|
{"name": "fitness_center", "tags": ["gym", "exercise", "workout"]},
|
||||||
|
{"name": "sports", "tags": ["athletics", "game", "activity"]},
|
||||||
|
{"name": "directions_car", "tags": ["car", "vehicle", "auto", "drive"]},
|
||||||
|
{"name": "directions_bus", "tags": ["bus", "transit", "transport"]},
|
||||||
|
{"name": "directions_bike", "tags": ["bicycle", "cycling", "bike"]},
|
||||||
|
{"name": "directions_walk", "tags": ["walk", "pedestrian", "foot"]},
|
||||||
|
{"name": "flight", "tags": ["plane", "airplane", "travel"]},
|
||||||
|
{"name": "train", "tags": ["rail", "transit", "transport"]},
|
||||||
|
{"name": "subway", "tags": ["metro", "underground", "transit"]},
|
||||||
|
{"name": "keyboard", "tags": ["type", "input", "keys"]},
|
||||||
|
{"name": "mouse", "tags": ["cursor", "click", "input"]},
|
||||||
|
{"name": "computer", "tags": ["desktop", "pc", "monitor"]},
|
||||||
|
{"name": "laptop", "tags": ["computer", "notebook", "device"]},
|
||||||
|
{"name": "smartphone", "tags": ["phone", "mobile", "device"]},
|
||||||
|
{"name": "tablet", "tags": ["ipad", "device", "screen"]},
|
||||||
|
{"name": "watch", "tags": ["time", "wearable", "smartwatch"]},
|
||||||
|
{"name": "headphones", "tags": ["audio", "music", "listen"]},
|
||||||
|
{"name": "speaker", "tags": ["audio", "sound", "music"]},
|
||||||
|
{"name": "tv", "tags": ["television", "screen", "display"]},
|
||||||
|
{"name": "print", "tags": ["printer", "document", "paper"]},
|
||||||
|
{"name": "scanner", "tags": ["scan", "copy", "document"]},
|
||||||
|
{"name": "usb", "tags": ["cable", "port", "connect"]},
|
||||||
|
{"name": "bluetooth", "tags": ["wireless", "connect", "pair"]},
|
||||||
|
{"name": "wifi", "tags": ["wireless", "internet", "network"]},
|
||||||
|
{"name": "signal_cellular_alt", "tags": ["mobile", "network", "bars"]},
|
||||||
|
{"name": "battery_full", "tags": ["power", "charge", "energy"]},
|
||||||
|
{"name": "battery_low", "tags": ["power", "charge", "low"]},
|
||||||
|
{"name": "power", "tags": ["on", "off", "switch"]},
|
||||||
|
{"name": "bolt", "tags": ["lightning", "flash", "power"]},
|
||||||
|
{"name": "brightness_high", "tags": ["sun", "light", "display"]},
|
||||||
|
{"name": "brightness_low", "tags": ["dim", "dark", "display"]},
|
||||||
|
{"name": "dark_mode", "tags": ["night", "moon", "theme"]},
|
||||||
|
{"name": "light_mode", "tags": ["day", "sun", "theme"]},
|
||||||
|
{"name": "thermostat", "tags": ["temperature", "climate", "heat"]},
|
||||||
|
{"name": "ac_unit", "tags": ["cooling", "air", "snowflake"]},
|
||||||
|
{"name": "wb_sunny", "tags": ["sun", "weather", "bright"]},
|
||||||
|
{"name": "cloud_queue", "tags": ["weather", "cloudy", "sky"]},
|
||||||
|
{"name": "water_drop", "tags": ["rain", "liquid", "droplet"]},
|
||||||
|
{"name": "air", "tags": ["wind", "breeze", "weather"]},
|
||||||
|
{"name": "eco", "tags": ["leaf", "nature", "green"]},
|
||||||
|
{"name": "park", "tags": ["tree", "nature", "outdoor"]},
|
||||||
|
{"name": "pets", "tags": ["paw", "animal", "dog"]},
|
||||||
|
{"name": "bug_report", "tags": ["insect", "issue", "debug"]},
|
||||||
|
{"name": "code", "tags": ["programming", "developer", "brackets"]},
|
||||||
|
{"name": "terminal", "tags": ["console", "command", "shell"]},
|
||||||
|
{"name": "data_object", "tags": ["json", "braces", "code"]},
|
||||||
|
{"name": "database", "tags": ["storage", "data", "server"]},
|
||||||
|
{"name": "dns", "tags": ["server", "network", "domain"]},
|
||||||
|
{"name": "storage", "tags": ["disk", "save", "memory"]},
|
||||||
|
{"name": "memory", "tags": ["ram", "chip", "hardware"]},
|
||||||
|
{"name": "developer_board", "tags": ["circuit", "hardware", "tech"]},
|
||||||
|
{"name": "build", "tags": ["wrench", "tool", "construct"]},
|
||||||
|
{"name": "construction", "tags": ["tools", "work", "build"]},
|
||||||
|
{"name": "handyman", "tags": ["tools", "repair", "fix"]},
|
||||||
|
{"name": "science", "tags": ["flask", "chemistry", "lab"]},
|
||||||
|
{"name": "biotech", "tags": ["dna", "genetics", "science"]},
|
||||||
|
{"name": "psychology", "tags": ["brain", "mind", "mental"]},
|
||||||
|
{"name": "medical_services", "tags": ["health", "hospital", "doctor"]},
|
||||||
|
{"name": "healing", "tags": ["bandage", "medical", "health"]},
|
||||||
|
{"name": "medication", "tags": ["pill", "drug", "pharmacy"]},
|
||||||
|
{"name": "vaccines", "tags": ["syringe", "injection", "medical"]},
|
||||||
|
{"name": "accessibility", "tags": ["person", "handicap", "access"]},
|
||||||
|
{"name": "elderly", "tags": ["senior", "old", "person"]},
|
||||||
|
{"name": "child_care", "tags": ["baby", "kid", "infant"]},
|
||||||
|
{"name": "family", "tags": ["people", "group", "parents"]},
|
||||||
|
{"name": "wc", "tags": ["toilet", "bathroom", "restroom"]},
|
||||||
|
{"name": "smoking_rooms", "tags": ["cigarette", "smoke", "tobacco"]},
|
||||||
|
{"name": "no_smoking", "tags": ["prohibited", "ban", "cigarette"]},
|
||||||
|
{"name": "language", "tags": ["globe", "world", "international"]},
|
||||||
|
{"name": "translate", "tags": ["language", "convert", "localize"]},
|
||||||
|
{"name": "font_download", "tags": ["typography", "text", "typeface"]},
|
||||||
|
{"name": "format_bold", "tags": ["text", "typography", "b"]},
|
||||||
|
{"name": "format_italic", "tags": ["text", "typography", "i"]},
|
||||||
|
{"name": "format_underlined", "tags": ["text", "typography", "u"]},
|
||||||
|
{"name": "format_strikethrough", "tags": ["text", "delete", "cross"]},
|
||||||
|
{"name": "format_size", "tags": ["text", "font", "typography"]},
|
||||||
|
{"name": "format_color_text", "tags": ["color", "font", "typography"]},
|
||||||
|
{"name": "format_color_fill", "tags": ["bucket", "paint", "color"]},
|
||||||
|
{"name": "format_align_left", "tags": ["text", "paragraph", "align"]},
|
||||||
|
{"name": "format_align_center", "tags": ["text", "paragraph", "align"]},
|
||||||
|
{"name": "format_align_right", "tags": ["text", "paragraph", "align"]},
|
||||||
|
{"name": "format_align_justify", "tags": ["text", "paragraph", "align"]},
|
||||||
|
{"name": "format_list_bulleted", "tags": ["list", "ul", "bullets"]},
|
||||||
|
{"name": "format_list_numbered", "tags": ["list", "ol", "numbers"]},
|
||||||
|
{"name": "format_quote", "tags": ["quotation", "blockquote", "cite"]},
|
||||||
|
{"name": "format_indent_increase", "tags": ["indent", "tab", "spacing"]},
|
||||||
|
{"name": "format_indent_decrease", "tags": ["outdent", "tab", "spacing"]},
|
||||||
|
{"name": "link", "tags": ["url", "chain", "hyperlink"]},
|
||||||
|
{"name": "link_off", "tags": ["unlink", "broken", "disconnect"]},
|
||||||
|
{"name": "image", "tags": ["photo", "picture", "media"]},
|
||||||
|
{"name": "insert_photo", "tags": ["image", "picture", "add"]},
|
||||||
|
{"name": "add_photo_alternate", "tags": ["image", "upload", "new"]},
|
||||||
|
{"name": "crop", "tags": ["image", "resize", "cut"]},
|
||||||
|
{"name": "rotate_left", "tags": ["image", "turn", "ccw"]},
|
||||||
|
{"name": "rotate_right", "tags": ["image", "turn", "cw"]},
|
||||||
|
{"name": "flip", "tags": ["mirror", "image", "reflect"]},
|
||||||
|
{"name": "filter", "tags": ["image", "effect", "adjust"]},
|
||||||
|
{"name": "tune", "tags": ["adjust", "settings", "sliders"]},
|
||||||
|
{"name": "palette", "tags": ["color", "paint", "art"]},
|
||||||
|
{"name": "brush", "tags": ["paint", "draw", "art"]},
|
||||||
|
{"name": "create", "tags": ["pencil", "edit", "write"]},
|
||||||
|
{"name": "draw", "tags": ["pencil", "sketch", "art"]},
|
||||||
|
{"name": "gesture", "tags": ["hand", "draw", "touch"]},
|
||||||
|
{"name": "shape_line", "tags": ["line", "draw", "shape"]},
|
||||||
|
{"name": "rectangle", "tags": ["square", "shape", "box"]},
|
||||||
|
{"name": "circle", "tags": ["shape", "round", "ellipse"]},
|
||||||
|
{"name": "hexagon", "tags": ["shape", "polygon", "six"]},
|
||||||
|
{"name": "pentagon", "tags": ["shape", "polygon", "five"]},
|
||||||
|
{"name": "change_history", "tags": ["triangle", "shape", "arrow"]},
|
||||||
|
{"name": "category", "tags": ["shapes", "organize", "sort"]},
|
||||||
|
{"name": "grid_view", "tags": ["layout", "tiles", "gallery"]},
|
||||||
|
{"name": "view_list", "tags": ["layout", "rows", "lines"]},
|
||||||
|
{"name": "view_module", "tags": ["layout", "grid", "blocks"]},
|
||||||
|
{"name": "view_agenda", "tags": ["layout", "cards", "list"]},
|
||||||
|
{"name": "dashboard", "tags": ["layout", "widgets", "overview"]},
|
||||||
|
{"name": "widgets", "tags": ["components", "blocks", "modules"]},
|
||||||
|
{"name": "layers", "tags": ["stack", "overlap", "design"]},
|
||||||
|
{"name": "aspect_ratio", "tags": ["resize", "scale", "dimensions"]},
|
||||||
|
{"name": "zoom_in", "tags": ["magnify", "enlarge", "plus"]},
|
||||||
|
{"name": "zoom_out", "tags": ["shrink", "reduce", "minus"]},
|
||||||
|
{"name": "fullscreen", "tags": ["expand", "maximize", "enlarge"]},
|
||||||
|
{"name": "fullscreen_exit", "tags": ["shrink", "minimize", "reduce"]},
|
||||||
|
{"name": "center_focus_strong", "tags": ["target", "aim", "focus"]},
|
||||||
|
{"name": "filter_center_focus", "tags": ["camera", "focus", "center"]},
|
||||||
|
{"name": "panorama", "tags": ["wide", "image", "photo"]},
|
||||||
|
{"name": "photo_library", "tags": ["gallery", "images", "album"]},
|
||||||
|
{"name": "collections", "tags": ["gallery", "photos", "album"]},
|
||||||
|
{"name": "slideshow", "tags": ["presentation", "play", "images"]},
|
||||||
|
{"name": "movie", "tags": ["film", "video", "cinema"]},
|
||||||
|
{"name": "theaters", "tags": ["cinema", "film", "drama"]},
|
||||||
|
{"name": "music_note", "tags": ["audio", "song", "melody"]},
|
||||||
|
{"name": "album", "tags": ["music", "record", "disc"]},
|
||||||
|
{"name": "radio", "tags": ["music", "broadcast", "audio"]},
|
||||||
|
{"name": "equalizer", "tags": ["audio", "levels", "music"]},
|
||||||
|
{"name": "graphic_eq", "tags": ["audio", "visualizer", "music"]},
|
||||||
|
{"name": "mic_none", "tags": ["microphone", "record", "audio"]},
|
||||||
|
{"name": "record_voice_over", "tags": ["speak", "voice", "narrate"]},
|
||||||
|
{"name": "hearing", "tags": ["ear", "listen", "audio"]},
|
||||||
|
{"name": "closed_caption", "tags": ["subtitles", "cc", "text"]},
|
||||||
|
{"name": "subtitles", "tags": ["cc", "captions", "text"]},
|
||||||
|
{"name": "hd", "tags": ["quality", "high", "resolution"]},
|
||||||
|
{"name": "4k", "tags": ["quality", "ultra", "resolution"]},
|
||||||
|
{"name": "speed", "tags": ["fast", "gauge", "performance"]},
|
||||||
|
{"name": "timer", "tags": ["clock", "countdown", "stopwatch"]},
|
||||||
|
{"name": "hourglass_empty", "tags": ["time", "wait", "loading"]},
|
||||||
|
{"name": "hourglass_full", "tags": ["time", "complete", "done"]},
|
||||||
|
{"name": "access_time", "tags": ["clock", "time", "schedule"]},
|
||||||
|
{"name": "alarm", "tags": ["clock", "alert", "reminder"]},
|
||||||
|
{"name": "alarm_on", "tags": ["clock", "active", "set"]},
|
||||||
|
{"name": "alarm_off", "tags": ["clock", "disabled", "silent"]},
|
||||||
|
{"name": "snooze", "tags": ["sleep", "delay", "alarm"]},
|
||||||
|
{"name": "event", "tags": ["calendar", "date", "schedule"]},
|
||||||
|
{"name": "event_available", "tags": ["calendar", "free", "open"]},
|
||||||
|
{"name": "event_busy", "tags": ["calendar", "occupied", "booked"]},
|
||||||
|
{"name": "today", "tags": ["calendar", "now", "current"]},
|
||||||
|
{"name": "date_range", "tags": ["calendar", "period", "span"]},
|
||||||
|
{"name": "update", "tags": ["refresh", "sync", "reload"]},
|
||||||
|
{"name": "history", "tags": ["time", "past", "clock"]},
|
||||||
|
{"name": "restore", "tags": ["undo", "back", "recover"]},
|
||||||
|
{"name": "undo", "tags": ["back", "reverse", "arrow"]},
|
||||||
|
{"name": "redo", "tags": ["forward", "repeat", "arrow"]},
|
||||||
|
{"name": "content_copy", "tags": ["copy", "duplicate", "clipboard"]},
|
||||||
|
{"name": "content_cut", "tags": ["scissors", "cut", "clipboard"]},
|
||||||
|
{"name": "content_paste", "tags": ["clipboard", "paste", "insert"]},
|
||||||
|
{"name": "select_all", "tags": ["checkbox", "all", "select"]},
|
||||||
|
{"name": "save", "tags": ["disk", "floppy", "store"]},
|
||||||
|
{"name": "save_as", "tags": ["disk", "export", "store"]},
|
||||||
|
{"name": "draft", "tags": ["document", "edit", "paper"]},
|
||||||
|
{"name": "note", "tags": ["paper", "memo", "text"]},
|
||||||
|
{"name": "note_add", "tags": ["document", "new", "create"]},
|
||||||
|
{"name": "description", "tags": ["document", "file", "text"]},
|
||||||
|
{"name": "article", "tags": ["document", "text", "news"]},
|
||||||
|
{"name": "newspaper", "tags": ["news", "article", "media"]},
|
||||||
|
{"name": "feed", "tags": ["rss", "news", "stream"]},
|
||||||
|
{"name": "rss_feed", "tags": ["news", "subscribe", "blog"]},
|
||||||
|
{"name": "bookmark", "tags": ["save", "favorite", "tag"]},
|
||||||
|
{"name": "bookmark_border", "tags": ["save", "favorite", "outline"]},
|
||||||
|
{"name": "bookmarks", "tags": ["saved", "favorites", "collection"]},
|
||||||
|
{"name": "label", "tags": ["tag", "category", "badge"]},
|
||||||
|
{"name": "sell", "tags": ["tag", "price", "sale"]},
|
||||||
|
{"name": "loyalty", "tags": ["heart", "tag", "reward"]},
|
||||||
|
{"name": "new_releases", "tags": ["starburst", "badge", "new"]},
|
||||||
|
{"name": "stars", "tags": ["rating", "favorite", "best"]},
|
||||||
|
{"name": "grade", "tags": ["star", "rating", "review"]},
|
||||||
|
{"name": "military_tech", "tags": ["medal", "badge", "award"]},
|
||||||
|
{"name": "emoji_events", "tags": ["trophy", "award", "winner"]},
|
||||||
|
{"name": "workspace_premium", "tags": ["badge", "crown", "premium"]},
|
||||||
|
{"name": "verified_user", "tags": ["shield", "check", "secure"]},
|
||||||
|
{"name": "admin_panel_settings", "tags": ["shield", "gear", "admin"]},
|
||||||
|
{"name": "manage_accounts", "tags": ["user", "settings", "admin"]},
|
||||||
|
{"name": "supervised_user_circle", "tags": ["admin", "user", "manage"]},
|
||||||
|
{"name": "group", "tags": ["people", "team", "users"]},
|
||||||
|
{"name": "group_add", "tags": ["people", "team", "invite"]},
|
||||||
|
{"name": "group_remove", "tags": ["people", "team", "delete"]},
|
||||||
|
{"name": "person_add", "tags": ["user", "invite", "new"]},
|
||||||
|
{"name": "person_remove", "tags": ["user", "delete", "remove"]},
|
||||||
|
{"name": "face", "tags": ["emoji", "person", "avatar"]},
|
||||||
|
{"name": "sentiment_very_satisfied", "tags": ["happy", "joy", "smile"]},
|
||||||
|
{"name": "sentiment_neutral", "tags": ["meh", "okay", "face"]},
|
||||||
|
{"name": "sentiment_very_dissatisfied", "tags": ["angry", "upset", "mad"]},
|
||||||
|
{"name": "mood_bad", "tags": ["sad", "unhappy", "frown"]},
|
||||||
|
{"name": "sick", "tags": ["ill", "unwell", "face"]},
|
||||||
|
{"name": "masks", "tags": ["theater", "drama", "comedy"]},
|
||||||
|
{"name": "cake", "tags": ["birthday", "celebration", "party"]},
|
||||||
|
{"name": "celebration", "tags": ["party", "confetti", "event"]},
|
||||||
|
{"name": "card_giftcard", "tags": ["gift", "present", "voucher"]},
|
||||||
|
{"name": "redeem", "tags": ["gift", "box", "present"]},
|
||||||
|
{"name": "volunteer_activism", "tags": ["heart", "hand", "donate"]},
|
||||||
|
{"name": "handshake", "tags": ["deal", "agreement", "partner"]},
|
||||||
|
{"name": "diversity_3", "tags": ["people", "team", "group"]},
|
||||||
|
{"name": "public", "tags": ["globe", "world", "earth"]},
|
||||||
|
{"name": "travel_explore", "tags": ["globe", "search", "world"]},
|
||||||
|
{"name": "flag", "tags": ["country", "nation", "report"]},
|
||||||
|
{"name": "tour", "tags": ["flag", "marker", "location"]},
|
||||||
|
{"name": "place", "tags": ["pin", "location", "marker"]},
|
||||||
|
{"name": "my_location", "tags": ["gps", "target", "current"]},
|
||||||
|
{"name": "near_me", "tags": ["location", "arrow", "nearby"]},
|
||||||
|
{"name": "explore", "tags": ["compass", "navigate", "discover"]},
|
||||||
|
{"name": "navigation", "tags": ["arrow", "direction", "gps"]},
|
||||||
|
{"name": "map", "tags": ["location", "geography", "atlas"]},
|
||||||
|
{"name": "satellite", "tags": ["space", "orbit", "map"]},
|
||||||
|
{"name": "terrain", "tags": ["mountain", "landscape", "map"]},
|
||||||
|
{"name": "layers_clear", "tags": ["stack", "remove", "design"]},
|
||||||
|
{"name": "streetview", "tags": ["map", "360", "view"]},
|
||||||
|
{"name": "traffic", "tags": ["signal", "light", "road"]},
|
||||||
|
{"name": "alt_route", "tags": ["path", "alternative", "direction"]},
|
||||||
|
{"name": "merge", "tags": ["combine", "join", "arrows"]},
|
||||||
|
{"name": "call_split", "tags": ["fork", "divide", "arrows"]},
|
||||||
|
{"name": "compare_arrows", "tags": ["swap", "exchange", "switch"]},
|
||||||
|
{"name": "swap_horiz", "tags": ["exchange", "switch", "horizontal"]},
|
||||||
|
{"name": "swap_vert", "tags": ["exchange", "switch", "vertical"]},
|
||||||
|
{"name": "import_export", "tags": ["arrows", "transfer", "data"]},
|
||||||
|
{"name": "arrow_upward", "tags": ["up", "direction", "top"]},
|
||||||
|
{"name": "arrow_downward", "tags": ["down", "direction", "bottom"]},
|
||||||
|
{"name": "arrow_forward", "tags": ["right", "direction", "next"]},
|
||||||
|
{"name": "arrow_back", "tags": ["left", "direction", "previous"]},
|
||||||
|
{"name": "north", "tags": ["up", "direction", "compass"]},
|
||||||
|
{"name": "south", "tags": ["down", "direction", "compass"]},
|
||||||
|
{"name": "east", "tags": ["right", "direction", "compass"]},
|
||||||
|
{"name": "west", "tags": ["left", "direction", "compass"]},
|
||||||
|
{"name": "expand_more", "tags": ["down", "chevron", "dropdown"]},
|
||||||
|
{"name": "expand_less", "tags": ["up", "chevron", "collapse"]},
|
||||||
|
{"name": "chevron_right", "tags": ["arrow", "right", "next"]},
|
||||||
|
{"name": "chevron_left", "tags": ["arrow", "left", "previous"]},
|
||||||
|
{"name": "unfold_more", "tags": ["expand", "vertical", "arrows"]},
|
||||||
|
{"name": "unfold_less", "tags": ["collapse", "vertical", "arrows"]},
|
||||||
|
{"name": "first_page", "tags": ["start", "beginning", "arrow"]},
|
||||||
|
{"name": "last_page", "tags": ["end", "final", "arrow"]},
|
||||||
|
{"name": "subdirectory_arrow_right", "tags": ["nested", "child", "sub"]},
|
||||||
|
{"name": "subdirectory_arrow_left", "tags": ["nested", "parent", "back"]},
|
||||||
|
{"name": "trending_up", "tags": ["arrow", "growth", "increase"]},
|
||||||
|
{"name": "trending_down", "tags": ["arrow", "decline", "decrease"]},
|
||||||
|
{"name": "trending_flat", "tags": ["arrow", "stable", "neutral"]},
|
||||||
|
{"name": "show_chart", "tags": ["graph", "line", "analytics"]},
|
||||||
|
{"name": "bar_chart", "tags": ["graph", "statistics", "analytics"]},
|
||||||
|
{"name": "pie_chart", "tags": ["graph", "statistics", "donut"]},
|
||||||
|
{"name": "bubble_chart", "tags": ["graph", "data", "visualization"]},
|
||||||
|
{"name": "scatter_plot", "tags": ["graph", "data", "points"]},
|
||||||
|
{"name": "analytics", "tags": ["chart", "data", "statistics"]},
|
||||||
|
{"name": "insights", "tags": ["chart", "data", "analysis"]},
|
||||||
|
{"name": "leaderboard", "tags": ["chart", "ranking", "bars"]},
|
||||||
|
{"name": "table_chart", "tags": ["spreadsheet", "data", "grid"]},
|
||||||
|
{"name": "table_view", "tags": ["grid", "data", "spreadsheet"]},
|
||||||
|
{"name": "table_rows", "tags": ["grid", "horizontal", "data"]},
|
||||||
|
{"name": "view_column", "tags": ["grid", "vertical", "layout"]},
|
||||||
|
{"name": "view_week", "tags": ["calendar", "columns", "schedule"]},
|
||||||
|
{"name": "view_day", "tags": ["calendar", "single", "schedule"]},
|
||||||
|
{"name": "timeline", "tags": ["history", "time", "events"]},
|
||||||
|
{"name": "account_tree", "tags": ["hierarchy", "org", "structure"]},
|
||||||
|
{"name": "hub", "tags": ["network", "nodes", "connected"]},
|
||||||
|
{"name": "workspaces", "tags": ["circles", "venn", "overlap"]},
|
||||||
|
{"name": "token", "tags": ["chip", "badge", "tag"]},
|
||||||
|
{"name": "api", "tags": ["code", "integration", "connect"]},
|
||||||
|
{"name": "extension", "tags": ["puzzle", "plugin", "addon"]},
|
||||||
|
{"name": "integration_instructions", "tags": ["code", "embed", "api"]},
|
||||||
|
{"name": "webhook", "tags": ["api", "callback", "hook"]},
|
||||||
|
{"name": "javascript", "tags": ["code", "programming", "js"]},
|
||||||
|
{"name": "css", "tags": ["code", "style", "web"]},
|
||||||
|
{"name": "html", "tags": ["code", "web", "markup"]},
|
||||||
|
{"name": "php", "tags": ["code", "programming", "web"]},
|
||||||
|
{"name": "deployed_code", "tags": ["box", "package", "release"]},
|
||||||
|
{"name": "package_2", "tags": ["box", "delivery", "shipping"]},
|
||||||
|
{"name": "inventory_2", "tags": ["box", "storage", "stock"]},
|
||||||
|
{"name": "move_to_inbox", "tags": ["archive", "box", "download"]},
|
||||||
|
{"name": "outbox", "tags": ["send", "upload", "mail"]},
|
||||||
|
{"name": "inbox", "tags": ["mail", "receive", "box"]},
|
||||||
|
{"name": "all_inbox", "tags": ["mail", "messages", "combined"]},
|
||||||
|
{"name": "mark_email_read", "tags": ["mail", "open", "check"]},
|
||||||
|
{"name": "mark_email_unread", "tags": ["mail", "new", "dot"]},
|
||||||
|
{"name": "drafts", "tags": ["mail", "edit", "compose"]},
|
||||||
|
{"name": "send", "tags": ["mail", "submit", "arrow"]},
|
||||||
|
{"name": "forward_to_inbox", "tags": ["mail", "forward", "arrow"]},
|
||||||
|
{"name": "reply", "tags": ["mail", "respond", "arrow"]},
|
||||||
|
{"name": "reply_all", "tags": ["mail", "respond", "group"]},
|
||||||
|
{"name": "mark_as_unread", "tags": ["mail", "new", "notification"]},
|
||||||
|
{"name": "markunread_mailbox", "tags": ["mail", "mailbox", "new"]},
|
||||||
|
{"name": "contact_mail", "tags": ["email", "person", "address"]},
|
||||||
|
{"name": "contact_phone", "tags": ["call", "person", "number"]},
|
||||||
|
{"name": "contacts", "tags": ["people", "address", "book"]},
|
||||||
|
{"name": "perm_contact_calendar", "tags": ["person", "schedule", "date"]},
|
||||||
|
{"name": "badge", "tags": ["id", "name", "tag"]},
|
||||||
|
{"name": "assignment", "tags": ["clipboard", "task", "document"]},
|
||||||
|
{"name": "assignment_ind", "tags": ["person", "task", "assign"]},
|
||||||
|
{"name": "assignment_turned_in", "tags": ["task", "done", "check"]},
|
||||||
|
{"name": "assignment_late", "tags": ["task", "overdue", "warning"]},
|
||||||
|
{"name": "assignment_return", "tags": ["task", "back", "arrow"]},
|
||||||
|
{"name": "task", "tags": ["checkbox", "todo", "done"]},
|
||||||
|
{"name": "task_alt", "tags": ["check", "circle", "done"]},
|
||||||
|
{"name": "checklist", "tags": ["tasks", "todo", "list"]},
|
||||||
|
{"name": "fact_check", "tags": ["clipboard", "verify", "check"]},
|
||||||
|
{"name": "rule", "tags": ["check", "cross", "decision"]},
|
||||||
|
{"name": "done", "tags": ["check", "complete", "success"]},
|
||||||
|
{"name": "done_all", "tags": ["check", "double", "complete"]},
|
||||||
|
{"name": "done_outline", "tags": ["check", "circle", "complete"]},
|
||||||
|
{"name": "check_circle", "tags": ["done", "success", "complete"]},
|
||||||
|
{"name": "check_box", "tags": ["done", "tick", "checked"]},
|
||||||
|
{"name": "check_box_outline_blank", "tags": ["empty", "unchecked", "box"]},
|
||||||
|
{"name": "indeterminate_check_box", "tags": ["partial", "minus", "box"]},
|
||||||
|
{"name": "radio_button_checked", "tags": ["selected", "option", "circle"]},
|
||||||
|
{"name": "radio_button_unchecked", "tags": ["empty", "option", "circle"]},
|
||||||
|
{"name": "toggle_on", "tags": ["switch", "enabled", "active"]},
|
||||||
|
{"name": "toggle_off", "tags": ["switch", "disabled", "inactive"]},
|
||||||
|
{"name": "add_circle", "tags": ["plus", "new", "create"]},
|
||||||
|
{"name": "remove_circle", "tags": ["minus", "delete", "subtract"]},
|
||||||
|
{"name": "cancel", "tags": ["x", "close", "remove"]},
|
||||||
|
{"name": "highlight_off", "tags": ["x", "remove", "circle"]},
|
||||||
|
{"name": "do_not_disturb", "tags": ["minus", "block", "circle"]},
|
||||||
|
{"name": "block", "tags": ["prohibited", "ban", "stop"]},
|
||||||
|
{"name": "not_interested", "tags": ["circle", "slash", "disabled"]},
|
||||||
|
{"name": "report", "tags": ["octagon", "warning", "flag"]},
|
||||||
|
{"name": "report_problem", "tags": ["triangle", "warning", "alert"]},
|
||||||
|
{"name": "priority_high", "tags": ["exclamation", "important", "alert"]},
|
||||||
|
{"name": "new_label", "tags": ["tag", "badge", "add"]},
|
||||||
|
{"name": "fiber_new", "tags": ["badge", "new", "fresh"]},
|
||||||
|
{"name": "auto_awesome", "tags": ["sparkle", "magic", "ai"]},
|
||||||
|
{"name": "auto_fix_high", "tags": ["wand", "magic", "auto"]},
|
||||||
|
{"name": "flare", "tags": ["light", "sparkle", "shine"]},
|
||||||
|
{"name": "flash_on", "tags": ["lightning", "power", "camera"]},
|
||||||
|
{"name": "flash_off", "tags": ["lightning", "disabled", "camera"]},
|
||||||
|
{"name": "flash_auto", "tags": ["lightning", "auto", "camera"]},
|
||||||
|
{"name": "highlight", "tags": ["marker", "pen", "text"]},
|
||||||
|
{"name": "colorize", "tags": ["eyedropper", "pick", "color"]},
|
||||||
|
{"name": "opacity", "tags": ["transparent", "drop", "alpha"]},
|
||||||
|
{"name": "gradient", "tags": ["color", "blend", "fade"]},
|
||||||
|
{"name": "texture", "tags": ["pattern", "surface", "material"]},
|
||||||
|
{"name": "vignette", "tags": ["photo", "effect", "fade"]},
|
||||||
|
{"name": "blur_on", "tags": ["effect", "focus", "soft"]},
|
||||||
|
{"name": "blur_off", "tags": ["sharp", "clear", "focus"]},
|
||||||
|
{"name": "hdr_on", "tags": ["photo", "range", "dynamic"]},
|
||||||
|
{"name": "filter_vintage", "tags": ["flower", "retro", "effect"]},
|
||||||
|
{"name": "filter_drama", "tags": ["cloud", "weather", "sky"]},
|
||||||
|
{"name": "filter_frames", "tags": ["border", "photo", "frame"]},
|
||||||
|
{"name": "monochrome_photos", "tags": ["bw", "grayscale", "filter"]},
|
||||||
|
{"name": "photo_filter", "tags": ["star", "effect", "image"]},
|
||||||
|
{"name": "looks", "tags": ["sparkle", "enhance", "effect"]},
|
||||||
|
{"name": "straighten", "tags": ["rotate", "align", "level"]},
|
||||||
|
{"name": "transform", "tags": ["resize", "scale", "edit"]},
|
||||||
|
{"name": "style", "tags": ["format", "design", "appearance"]},
|
||||||
|
{"name": "format_paint", "tags": ["brush", "style", "copy"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
418
native/wordpress/maple-icons-wp/presets/phosphor.json
Normal file
418
native/wordpress/maple-icons-wp/presets/phosphor.json
Normal file
|
|
@ -0,0 +1,418 @@
|
||||||
|
{
|
||||||
|
"slug": "phosphor",
|
||||||
|
"name": "Phosphor",
|
||||||
|
"version": "2.1.1",
|
||||||
|
"icons": [
|
||||||
|
{"name": "activity", "tags": ["pulse", "health", "heart"], "category": "health", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "address-book", "tags": ["contacts", "directory", "people"], "category": "office", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "airplane", "tags": ["flight", "travel", "plane"], "category": "travel", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "airplane-in-flight", "tags": ["flight", "travel", "plane"], "category": "travel", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "airplane-landing", "tags": ["flight", "arrival", "plane"], "category": "travel", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "airplane-takeoff", "tags": ["flight", "departure", "plane"], "category": "travel", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "alarm", "tags": ["clock", "time", "alert"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "alien", "tags": ["space", "ufo", "extraterrestrial"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-bottom", "tags": ["layout", "vertical", "align"], "category": "design", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-center-horizontal", "tags": ["layout", "horizontal", "align"], "category": "design", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-center-vertical", "tags": ["layout", "vertical", "align"], "category": "design", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-left", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-right", "tags": ["text", "format", "paragraph"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "align-top", "tags": ["layout", "vertical", "align"], "category": "design", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "anchor", "tags": ["marine", "ship", "link"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "aperture", "tags": ["camera", "lens", "photo"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "archive", "tags": ["box", "storage", "files"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "archive-box", "tags": ["storage", "container", "files"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "armchair", "tags": ["furniture", "seat", "chair"], "category": "furniture", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-arc-left", "tags": ["direction", "curved", "back"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-arc-right", "tags": ["direction", "curved", "forward"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-double-up-left", "tags": ["direction", "turn", "back"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-double-up-right", "tags": ["direction", "turn", "forward"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-down-left", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-down-right", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-left-down", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-left-up", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-right-down", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-right-up", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-up-left", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-bend-up-right", "tags": ["direction", "turn", "corner"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-down", "tags": ["direction", "download", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-down-left", "tags": ["direction", "diagonal", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-down-right", "tags": ["direction", "diagonal", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-left", "tags": ["direction", "back", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-right", "tags": ["direction", "forward", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-up", "tags": ["direction", "upload", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-up-left", "tags": ["direction", "diagonal", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-circle-up-right", "tags": ["direction", "diagonal", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-clockwise", "tags": ["refresh", "reload", "sync"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-counter-clockwise", "tags": ["undo", "back", "history"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-down", "tags": ["direction", "down", "download"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-down-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-down-right", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-fat-down", "tags": ["direction", "down", "bold"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-fat-left", "tags": ["direction", "left", "bold"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-fat-right", "tags": ["direction", "right", "bold"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-fat-up", "tags": ["direction", "up", "bold"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-left", "tags": ["direction", "back", "previous"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-line-down", "tags": ["direction", "download", "end"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-line-left", "tags": ["direction", "start", "begin"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-line-right", "tags": ["direction", "end", "finish"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-line-up", "tags": ["direction", "upload", "top"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-right", "tags": ["direction", "forward", "next"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-square-down", "tags": ["direction", "download", "square"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-square-left", "tags": ["direction", "back", "square"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-square-right", "tags": ["direction", "forward", "square"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-square-up", "tags": ["direction", "upload", "square"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-down-left", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-down-right", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-left-down", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-left-up", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-right-down", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-right-up", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-up-left", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-u-up-right", "tags": ["direction", "turn", "uturn"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-up", "tags": ["direction", "up", "upload"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-up-left", "tags": ["direction", "diagonal"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrow-up-right", "tags": ["direction", "diagonal", "external"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-clockwise", "tags": ["refresh", "sync", "rotate"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-counter-clockwise", "tags": ["refresh", "sync", "rotate"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-down-up", "tags": ["sort", "swap", "vertical"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-horizontal", "tags": ["resize", "horizontal", "expand"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-in", "tags": ["collapse", "minimize", "shrink"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-in-cardinal", "tags": ["collapse", "center", "focus"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-in-line-horizontal", "tags": ["collapse", "horizontal"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-in-line-vertical", "tags": ["collapse", "vertical"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-in-simple", "tags": ["collapse", "minimize"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-left-right", "tags": ["swap", "horizontal", "exchange"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-merge", "tags": ["combine", "join", "merge"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-out", "tags": ["expand", "maximize", "fullscreen"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-out-cardinal", "tags": ["expand", "move", "directions"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-out-line-horizontal", "tags": ["expand", "horizontal"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-out-line-vertical", "tags": ["expand", "vertical"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-out-simple", "tags": ["expand", "maximize"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-split", "tags": ["fork", "divide", "branch"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "arrows-vertical", "tags": ["resize", "vertical", "expand"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "at", "tags": ["email", "mention", "at sign"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "atom", "tags": ["science", "physics", "nuclear"], "category": "science", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "baby", "tags": ["child", "infant", "kid"], "category": "people", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "backpack", "tags": ["bag", "school", "travel"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bag", "tags": ["shopping", "tote", "carry"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bag-simple", "tags": ["shopping", "tote", "simple"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "balloon", "tags": ["party", "celebration", "birthday"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bank", "tags": ["finance", "money", "building"], "category": "buildings", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "barbell", "tags": ["gym", "fitness", "weight"], "category": "fitness", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "barcode", "tags": ["scan", "product", "code"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "basket", "tags": ["shopping", "cart", "store"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "basketball", "tags": ["sport", "ball", "game"], "category": "sports", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bathtub", "tags": ["bathroom", "bath", "clean"], "category": "home", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-charging", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-charging-vertical", "tags": ["power", "energy", "charge"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-empty", "tags": ["power", "energy", "empty"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-full", "tags": ["power", "energy", "full"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-high", "tags": ["power", "energy", "high"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-low", "tags": ["power", "energy", "low"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-medium", "tags": ["power", "energy", "half"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-plus", "tags": ["power", "add", "charge"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-vertical-empty", "tags": ["power", "energy", "empty"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-vertical-full", "tags": ["power", "energy", "full"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-vertical-high", "tags": ["power", "energy", "high"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-vertical-low", "tags": ["power", "energy", "low"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-vertical-medium", "tags": ["power", "energy", "half"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-warning", "tags": ["power", "alert", "low"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "battery-warning-vertical", "tags": ["power", "alert", "low"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell", "tags": ["notification", "alert", "alarm"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-ringing", "tags": ["notification", "alert", "alarm"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-simple", "tags": ["notification", "alert", "simple"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-simple-ringing", "tags": ["notification", "alert", "alarm"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-simple-slash", "tags": ["notification", "mute", "off"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-simple-z", "tags": ["notification", "snooze", "sleep"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-slash", "tags": ["notification", "mute", "off"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bell-z", "tags": ["notification", "snooze", "sleep"], "category": "notifications", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bluetooth", "tags": ["wireless", "connection", "device"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bluetooth-connected", "tags": ["wireless", "paired", "device"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bluetooth-slash", "tags": ["wireless", "disabled", "off"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bluetooth-x", "tags": ["wireless", "disconnect", "error"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "book", "tags": ["read", "library", "education"], "category": "education", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "book-bookmark", "tags": ["saved", "favorite", "reading"], "category": "education", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "book-open", "tags": ["read", "library", "education"], "category": "education", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "book-open-text", "tags": ["read", "content", "article"], "category": "education", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bookmark", "tags": ["save", "favorite", "tag"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bookmark-simple", "tags": ["save", "favorite", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bookmarks", "tags": ["saved", "favorites", "collection"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bookmarks-simple", "tags": ["saved", "favorites", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bounding-box", "tags": ["selection", "area", "crop"], "category": "design", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "briefcase", "tags": ["work", "job", "business"], "category": "business", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "briefcase-metal", "tags": ["work", "job", "metal"], "category": "business", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "browser", "tags": ["web", "internet", "window"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "browsers", "tags": ["web", "windows", "tabs"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bug", "tags": ["insect", "error", "debug"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bug-beetle", "tags": ["insect", "beetle", "bug"], "category": "nature", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "bug-droid", "tags": ["android", "robot", "bug"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "buildings", "tags": ["city", "office", "skyline"], "category": "buildings", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calculator", "tags": ["math", "numbers", "compute"], "category": "tools", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calendar", "tags": ["date", "schedule", "event"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calendar-blank", "tags": ["date", "schedule", "empty"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calendar-check", "tags": ["date", "done", "confirmed"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calendar-plus", "tags": ["date", "add", "new"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "calendar-x", "tags": ["date", "cancel", "remove"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "camera", "tags": ["photo", "picture", "image"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "camera-slash", "tags": ["photo", "disabled", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "car", "tags": ["vehicle", "auto", "drive"], "category": "transportation", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "car-simple", "tags": ["vehicle", "auto", "simple"], "category": "transportation", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-circle-down", "tags": ["arrow", "down", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-circle-left", "tags": ["arrow", "left", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-circle-right", "tags": ["arrow", "right", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-circle-up", "tags": ["arrow", "up", "circle"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-down", "tags": ["arrow", "down", "expand"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-left", "tags": ["arrow", "left", "back"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-right", "tags": ["arrow", "right", "forward"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "caret-up", "tags": ["arrow", "up", "collapse"], "category": "arrows", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-bar", "tags": ["analytics", "graph", "data"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-bar-horizontal", "tags": ["analytics", "graph", "horizontal"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-line", "tags": ["analytics", "graph", "trend"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-line-down", "tags": ["analytics", "decrease", "trend"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-line-up", "tags": ["analytics", "increase", "trend"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-pie", "tags": ["analytics", "graph", "pie"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chart-pie-slice", "tags": ["analytics", "graph", "segment"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat", "tags": ["message", "conversation", "talk"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-centered", "tags": ["message", "conversation", "center"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-centered-dots", "tags": ["message", "typing", "dots"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-centered-text", "tags": ["message", "text", "conversation"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-circle", "tags": ["message", "conversation", "circle"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-circle-dots", "tags": ["message", "typing", "circle"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-circle-text", "tags": ["message", "text", "circle"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-dots", "tags": ["message", "typing", "dots"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chat-text", "tags": ["message", "text", "conversation"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chats", "tags": ["messages", "conversations", "multiple"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "chats-circle", "tags": ["messages", "conversations", "circles"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "check", "tags": ["done", "complete", "success"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "check-circle", "tags": ["done", "complete", "circle"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "check-square", "tags": ["done", "checkbox", "complete"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "circle", "tags": ["shape", "dot", "round"], "category": "shapes", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "circle-dashed", "tags": ["shape", "dashed", "border"], "category": "shapes", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "circle-half", "tags": ["shape", "half", "contrast"], "category": "shapes", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "circle-half-tilt", "tags": ["shape", "half", "tilt"], "category": "shapes", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "circle-notch", "tags": ["loading", "spinner", "progress"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clipboard", "tags": ["copy", "paste", "board"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clipboard-text", "tags": ["copy", "paste", "text"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clock", "tags": ["time", "watch", "schedule"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clock-afternoon", "tags": ["time", "pm", "afternoon"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clock-clockwise", "tags": ["time", "rotate", "forward"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "clock-counter-clockwise", "tags": ["time", "rotate", "back"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud", "tags": ["weather", "storage", "sky"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-arrow-down", "tags": ["download", "cloud", "save"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-arrow-up", "tags": ["upload", "cloud", "sync"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-check", "tags": ["cloud", "done", "synced"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-fog", "tags": ["weather", "fog", "mist"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-lightning", "tags": ["weather", "storm", "thunder"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-moon", "tags": ["weather", "night", "cloudy"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-rain", "tags": ["weather", "rain", "precipitation"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-slash", "tags": ["cloud", "offline", "disconnect"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-snow", "tags": ["weather", "snow", "winter"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-sun", "tags": ["weather", "day", "partly cloudy"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-warning", "tags": ["cloud", "alert", "error"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cloud-x", "tags": ["cloud", "error", "disconnect"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "code", "tags": ["programming", "html", "brackets"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "code-block", "tags": ["programming", "snippet", "code"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "code-simple", "tags": ["programming", "brackets", "simple"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "coffee", "tags": ["drink", "cup", "cafe"], "category": "food", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "command", "tags": ["keyboard", "mac", "shortcut"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "compass", "tags": ["navigation", "direction", "explore"], "category": "navigation", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "copy", "tags": ["duplicate", "clipboard", "clone"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "copy-simple", "tags": ["duplicate", "clone", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "credit-card", "tags": ["payment", "card", "money"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "crop", "tags": ["image", "edit", "resize"], "category": "editing", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cube", "tags": ["3d", "box", "shape"], "category": "shapes", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "currency-btc", "tags": ["bitcoin", "crypto", "currency"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "currency-dollar", "tags": ["money", "usd", "currency"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "currency-eur", "tags": ["money", "euro", "currency"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "currency-gbp", "tags": ["money", "pound", "currency"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "currency-jpy", "tags": ["money", "yen", "currency"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cursor", "tags": ["pointer", "mouse", "click"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "cursor-click", "tags": ["pointer", "click", "select"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "database", "tags": ["storage", "data", "server"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "desktop", "tags": ["computer", "monitor", "screen"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "desktop-tower", "tags": ["computer", "pc", "tower"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "device-mobile", "tags": ["phone", "mobile", "smartphone"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "device-tablet", "tags": ["tablet", "ipad", "device"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "download", "tags": ["save", "export", "arrow"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "download-simple", "tags": ["save", "export", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "envelope", "tags": ["email", "mail", "message"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "envelope-open", "tags": ["email", "mail", "read"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "envelope-simple", "tags": ["email", "mail", "simple"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "eye", "tags": ["view", "visible", "show"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "eye-closed", "tags": ["hide", "invisible", "hidden"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "eye-slash", "tags": ["hide", "invisible", "hidden"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file", "tags": ["document", "page", "paper"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file-arrow-down", "tags": ["download", "document", "save"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file-arrow-up", "tags": ["upload", "document", "export"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file-code", "tags": ["code", "programming", "document"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file-plus", "tags": ["add", "new", "document"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "file-text", "tags": ["document", "text", "content"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "filter", "tags": ["funnel", "sort", "search"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "flag", "tags": ["report", "mark", "country"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "folder", "tags": ["directory", "files", "organize"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "folder-open", "tags": ["directory", "browse", "explore"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "folder-plus", "tags": ["directory", "add", "new"], "category": "files", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "funnel", "tags": ["filter", "sort", "funnel"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "gear", "tags": ["settings", "cog", "config"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "gear-six", "tags": ["settings", "cog", "config"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "gift", "tags": ["present", "reward", "surprise"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "globe", "tags": ["world", "earth", "web"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "globe-hemisphere-east", "tags": ["world", "earth", "asia"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "globe-hemisphere-west", "tags": ["world", "earth", "americas"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "grid-four", "tags": ["layout", "grid", "squares"], "category": "layout", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "hand", "tags": ["palm", "stop", "gesture"], "category": "gestures", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "hand-pointing", "tags": ["finger", "point", "gesture"], "category": "gestures", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "hash", "tags": ["tag", "hashtag", "number"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "heart", "tags": ["love", "favorite", "like"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "heart-break", "tags": ["love", "broken", "sad"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "house", "tags": ["home", "building", "main"], "category": "buildings", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "house-simple", "tags": ["home", "building", "simple"], "category": "buildings", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "image", "tags": ["picture", "photo", "gallery"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "image-square", "tags": ["picture", "photo", "square"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "info", "tags": ["information", "help", "about"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "key", "tags": ["password", "security", "lock"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "keyboard", "tags": ["typing", "input", "keys"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "laptop", "tags": ["computer", "notebook", "device"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "link", "tags": ["url", "chain", "connect"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "link-break", "tags": ["unlink", "disconnect", "broken"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "list", "tags": ["menu", "items", "bullet"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "list-bullets", "tags": ["menu", "items", "bullet"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "list-checks", "tags": ["tasks", "checklist", "todo"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "list-numbers", "tags": ["menu", "items", "ordered"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "lock", "tags": ["security", "private", "password"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "lock-key", "tags": ["security", "password", "key"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "lock-key-open", "tags": ["security", "unlocked", "open"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "lock-open", "tags": ["security", "unlocked", "open"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "magnifying-glass", "tags": ["search", "find", "zoom"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "magnifying-glass-minus", "tags": ["zoom out", "search", "smaller"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "magnifying-glass-plus", "tags": ["zoom in", "search", "bigger"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "map-pin", "tags": ["location", "marker", "place"], "category": "maps", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "map-trifold", "tags": ["navigation", "directions", "map"], "category": "maps", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "megaphone", "tags": ["announce", "broadcast", "marketing"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "microphone", "tags": ["audio", "voice", "record"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "microphone-slash", "tags": ["audio", "mute", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "minus", "tags": ["subtract", "remove", "delete"], "category": "math", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "minus-circle", "tags": ["subtract", "remove", "circle"], "category": "math", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "moon", "tags": ["dark", "night", "theme"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "moon-stars", "tags": ["night", "dark", "stars"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "music-note", "tags": ["audio", "sound", "melody"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "music-notes", "tags": ["audio", "sound", "melody"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "navigation-arrow", "tags": ["direction", "compass", "arrow"], "category": "navigation", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "paper-plane", "tags": ["send", "message", "mail"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "paper-plane-right", "tags": ["send", "submit", "forward"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "paper-plane-tilt", "tags": ["send", "message", "tilt"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "paperclip", "tags": ["attachment", "file", "clip"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "paperclip-horizontal", "tags": ["attachment", "file", "horizontal"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "pause", "tags": ["media", "stop", "wait"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "pause-circle", "tags": ["media", "stop", "circle"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "pencil", "tags": ["edit", "write", "draw"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "pencil-line", "tags": ["edit", "write", "underline"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "pencil-simple", "tags": ["edit", "write", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "phone", "tags": ["call", "contact", "mobile"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "phone-call", "tags": ["call", "ringing", "incoming"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "play", "tags": ["media", "start", "video"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "play-circle", "tags": ["media", "start", "circle"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "plus", "tags": ["add", "create", "new"], "category": "math", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "plus-circle", "tags": ["add", "create", "circle"], "category": "math", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "power", "tags": ["on", "off", "shutdown"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "printer", "tags": ["print", "document", "paper"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "question", "tags": ["help", "support", "faq"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "rocket", "tags": ["launch", "startup", "space"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "rocket-launch", "tags": ["launch", "startup", "deploy"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "rss", "tags": ["feed", "subscribe", "blog"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "rss-simple", "tags": ["feed", "subscribe", "simple"], "category": "communication", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "scissors", "tags": ["cut", "trim", "edit"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "share", "tags": ["social", "send", "forward"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "share-network", "tags": ["social", "connect", "network"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "shield", "tags": ["security", "protection", "safe"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "shield-check", "tags": ["security", "verified", "safe"], "category": "security", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "shopping-bag", "tags": ["shop", "purchase", "buy"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "shopping-cart", "tags": ["shop", "cart", "ecommerce"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sign-in", "tags": ["login", "enter", "access"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sign-out", "tags": ["logout", "exit", "leave"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sliders", "tags": ["settings", "controls", "adjust"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sliders-horizontal", "tags": ["settings", "controls", "horizontal"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "smiley", "tags": ["emoji", "happy", "face"], "category": "emoji", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "smiley-sad", "tags": ["emoji", "sad", "face"], "category": "emoji", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sparkle", "tags": ["magic", "new", "shine"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-high", "tags": ["audio", "volume", "loud"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-low", "tags": ["audio", "volume", "quiet"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-none", "tags": ["audio", "mute", "silent"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-simple-high", "tags": ["audio", "volume", "loud"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-simple-low", "tags": ["audio", "volume", "quiet"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-simple-none", "tags": ["audio", "mute", "silent"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-simple-slash", "tags": ["audio", "mute", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-simple-x", "tags": ["audio", "mute", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-slash", "tags": ["audio", "mute", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "speaker-x", "tags": ["audio", "mute", "off"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "spinner", "tags": ["loading", "wait", "progress"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "spinner-gap", "tags": ["loading", "wait", "progress"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "star", "tags": ["favorite", "rating", "bookmark"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "star-four", "tags": ["sparkle", "magic", "star"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "star-half", "tags": ["rating", "half", "partial"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "stop", "tags": ["media", "stop", "end"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "stop-circle", "tags": ["media", "stop", "circle"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sun", "tags": ["light", "day", "brightness"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "sun-dim", "tags": ["light", "dim", "brightness"], "category": "weather", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "tag", "tags": ["label", "category", "price"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "target", "tags": ["goal", "aim", "focus"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "terminal", "tags": ["console", "command", "code"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "terminal-window", "tags": ["console", "command", "window"], "category": "development", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-aa", "tags": ["font", "typography", "text"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-align-center", "tags": ["text", "format", "center"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-align-justify", "tags": ["text", "format", "justify"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-align-left", "tags": ["text", "format", "left"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-align-right", "tags": ["text", "format", "right"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-b", "tags": ["bold", "format", "strong"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-italic", "tags": ["italic", "format", "emphasis"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-strikethrough", "tags": ["strikethrough", "format", "delete"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "text-underline", "tags": ["underline", "format", "text"], "category": "text", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "thumbs-down", "tags": ["dislike", "bad", "negative"], "category": "gestures", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "thumbs-up", "tags": ["like", "good", "positive"], "category": "gestures", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "ticket", "tags": ["event", "pass", "coupon"], "category": "objects", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "timer", "tags": ["time", "countdown", "clock"], "category": "time", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "toggle-left", "tags": ["switch", "off", "disable"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "toggle-right", "tags": ["switch", "on", "enable"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "trash", "tags": ["delete", "remove", "bin"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "trash-simple", "tags": ["delete", "remove", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "trend-down", "tags": ["chart", "decrease", "analytics"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "trend-up", "tags": ["chart", "increase", "analytics"], "category": "charts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "trophy", "tags": ["award", "winner", "achievement"], "category": "awards", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "truck", "tags": ["delivery", "shipping", "transport"], "category": "transportation", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "tv", "tags": ["television", "screen", "display"], "category": "devices", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "upload", "tags": ["export", "send", "share"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "upload-simple", "tags": ["export", "send", "simple"], "category": "actions", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user", "tags": ["person", "account", "profile"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-circle", "tags": ["avatar", "profile", "account"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-circle-gear", "tags": ["settings", "account", "config"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-circle-minus", "tags": ["remove", "unfriend", "user"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-circle-plus", "tags": ["add", "invite", "user"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-focus", "tags": ["target", "focus", "user"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-gear", "tags": ["settings", "account", "config"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-list", "tags": ["contacts", "directory", "users"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-minus", "tags": ["remove", "unfriend", "delete"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-plus", "tags": ["add", "invite", "new"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-rectangle", "tags": ["id", "card", "profile"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "user-square", "tags": ["avatar", "profile", "square"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "users", "tags": ["people", "team", "group"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "users-four", "tags": ["people", "team", "group"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "users-three", "tags": ["people", "team", "group"], "category": "users", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "video-camera", "tags": ["video", "film", "record"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "video-camera-slash", "tags": ["video", "off", "mute"], "category": "media", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wallet", "tags": ["money", "payment", "finance"], "category": "commerce", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "warning", "tags": ["alert", "error", "caution"], "category": "alerts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "warning-circle", "tags": ["alert", "error", "circle"], "category": "alerts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "warning-diamond", "tags": ["alert", "error", "diamond"], "category": "alerts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "warning-octagon", "tags": ["alert", "stop", "error"], "category": "alerts", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-high", "tags": ["wireless", "internet", "strong"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-low", "tags": ["wireless", "internet", "weak"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-medium", "tags": ["wireless", "internet", "medium"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-none", "tags": ["wireless", "offline", "disconnect"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-slash", "tags": ["wireless", "offline", "disconnect"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wifi-x", "tags": ["wireless", "error", "disconnect"], "category": "connectivity", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "wrench", "tags": ["tool", "settings", "repair"], "category": "tools", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "x", "tags": ["close", "cancel", "remove"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "x-circle", "tags": ["close", "cancel", "error"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]},
|
||||||
|
{"name": "x-square", "tags": ["close", "cancel", "remove"], "category": "ui", "styles": ["regular", "bold", "light", "thin", "fill", "duotone"]}
|
||||||
|
]
|
||||||
|
}
|
||||||
124
native/wordpress/maple-icons-wp/readme.txt
Normal file
124
native/wordpress/maple-icons-wp/readme.txt
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
=== Maple Icons ===
|
||||||
|
Contributors: jetrails
|
||||||
|
Tags: icons, svg, gutenberg, block, heroicons, lucide, feather, phosphor, material
|
||||||
|
Requires at least: 6.5
|
||||||
|
Tested up to: 6.7
|
||||||
|
Stable tag: 1.0.0
|
||||||
|
Requires PHP: 7.4
|
||||||
|
License: GPLv2 or later
|
||||||
|
License URI: https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
|
||||||
|
Insert beautiful open-source icons into your content with a Gutenberg block. Download icon sets from CDN and serve locally.
|
||||||
|
|
||||||
|
== Description ==
|
||||||
|
|
||||||
|
Maple Icons provides a simple way to insert high-quality, open-source icons into your WordPress content using the Gutenberg block editor.
|
||||||
|
|
||||||
|
= Features =
|
||||||
|
|
||||||
|
* **Multiple Icon Sets** - Choose from popular open-source icon libraries:
|
||||||
|
* Heroicons (~290 icons) - MIT License
|
||||||
|
* Lucide (~1400 icons) - ISC License
|
||||||
|
* Feather (~287 icons) - MIT License
|
||||||
|
* Phosphor (~1200 icons per style) - MIT License
|
||||||
|
* Material Symbols (~400 icons) - Apache 2.0 License
|
||||||
|
|
||||||
|
* **Local Storage** - Icons are downloaded from CDN and stored locally in your WordPress installation. No external requests are made when displaying icons on your site.
|
||||||
|
|
||||||
|
* **Gutenberg Block** - Easy-to-use block with:
|
||||||
|
* Search and filter icons
|
||||||
|
* Multiple style variants per set
|
||||||
|
* Size control (12px - 256px)
|
||||||
|
* Custom icon color
|
||||||
|
* Background color
|
||||||
|
* Padding and margin controls
|
||||||
|
* Stroke width adjustment
|
||||||
|
* Drop shadow effect
|
||||||
|
|
||||||
|
* **Performance Optimized**
|
||||||
|
* Icons are inline SVG - no additional HTTP requests
|
||||||
|
* No frontend JavaScript or CSS
|
||||||
|
* Works in RSS feeds and email
|
||||||
|
|
||||||
|
* **Accessible**
|
||||||
|
* Decorative icons automatically hidden from screen readers
|
||||||
|
* Optional accessible labels for meaningful icons
|
||||||
|
* Follows WCAG guidelines
|
||||||
|
|
||||||
|
= How It Works =
|
||||||
|
|
||||||
|
1. Go to Settings → Maple Icons
|
||||||
|
2. Download one or more icon sets
|
||||||
|
3. Set one icon set as active
|
||||||
|
4. In the Gutenberg editor, add a "Maple Icon" block
|
||||||
|
5. Search and select an icon
|
||||||
|
6. Customize size, color, and other settings
|
||||||
|
|
||||||
|
= Icon Storage =
|
||||||
|
|
||||||
|
Downloaded icons are stored in `wp-content/maple-icons/`. Each icon set is stored in its own subdirectory with the SVG files organized by style.
|
||||||
|
|
||||||
|
= Compatibility =
|
||||||
|
|
||||||
|
* WordPress 6.5+
|
||||||
|
* PHP 7.4+
|
||||||
|
* WooCommerce (HPOS compatible)
|
||||||
|
* Works with all properly coded themes
|
||||||
|
* Compatible with popular page builders that support Gutenberg blocks
|
||||||
|
|
||||||
|
== Installation ==
|
||||||
|
|
||||||
|
1. Upload the `maple-icons` folder to the `/wp-content/plugins/` directory
|
||||||
|
2. Activate the plugin through the 'Plugins' menu in WordPress
|
||||||
|
3. Go to Settings → Maple Icons to download icon sets
|
||||||
|
4. Start using the "Maple Icon" block in your content
|
||||||
|
|
||||||
|
== Frequently Asked Questions ==
|
||||||
|
|
||||||
|
= Are the icons free to use? =
|
||||||
|
|
||||||
|
Yes! All icon sets included are open-source with permissive licenses (MIT, ISC, or Apache 2.0) that allow commercial use.
|
||||||
|
|
||||||
|
= Can I use multiple icon sets? =
|
||||||
|
|
||||||
|
You can download multiple icon sets, but only one can be active at a time. The active set is what appears in the Gutenberg block icon picker.
|
||||||
|
|
||||||
|
= Where are the icons stored? =
|
||||||
|
|
||||||
|
Icons are downloaded from CDN (jsdelivr.net) and stored locally in `wp-content/maple-icons/`. Once downloaded, no external requests are made to display icons.
|
||||||
|
|
||||||
|
= How do I change the icon color? =
|
||||||
|
|
||||||
|
Icons automatically inherit the text color from your theme. You can also set a custom color in the block settings panel.
|
||||||
|
|
||||||
|
= Will icons work in RSS feeds? =
|
||||||
|
|
||||||
|
Yes! Icons are saved as inline SVG in your post content, so they work in RSS feeds, email newsletters, and anywhere else your content is displayed.
|
||||||
|
|
||||||
|
= What happens if I uninstall the plugin? =
|
||||||
|
|
||||||
|
Existing icons in your content will remain as inline SVG. However, you won't be able to add new icons or use the block settings. The downloaded icon files in `wp-content/maple-icons/` will be removed on uninstall.
|
||||||
|
|
||||||
|
= Is this plugin GDPR compliant? =
|
||||||
|
|
||||||
|
Yes. Maple Icons does not collect any user data, set cookies, or make external requests after icons are downloaded. All icon files are stored locally on your server.
|
||||||
|
|
||||||
|
== Screenshots ==
|
||||||
|
|
||||||
|
1. Settings page - Download and manage icon sets
|
||||||
|
2. Icon picker modal in Gutenberg editor
|
||||||
|
3. Block settings panel with customization options
|
||||||
|
4. Icon block rendered on the frontend
|
||||||
|
|
||||||
|
== Changelog ==
|
||||||
|
|
||||||
|
= 1.0.0 =
|
||||||
|
* Initial release
|
||||||
|
* Support for Heroicons, Lucide, Feather, Phosphor, and Material Symbols
|
||||||
|
* Gutenberg block with full customization options
|
||||||
|
* Local icon storage
|
||||||
|
|
||||||
|
== Upgrade Notice ==
|
||||||
|
|
||||||
|
= 1.0.0 =
|
||||||
|
Initial release of Maple Icons.
|
||||||
5
native/wordpress/maple-icons-wp/src/index.php
Normal file
5
native/wordpress/maple-icons-wp/src/index.php
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
<?php
|
||||||
|
// Silence is golden.
|
||||||
|
if ( ! defined( 'ABSPATH' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
62
native/wordpress/maple-icons-wp/uninstall.php
Normal file
62
native/wordpress/maple-icons-wp/uninstall.php
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Maple Icons Uninstall
|
||||||
|
*
|
||||||
|
* Runs when the plugin is uninstalled (deleted).
|
||||||
|
* Cleans up all plugin data including downloaded icons and settings.
|
||||||
|
*
|
||||||
|
* @package MapleIcons
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exit if not called by WordPress.
|
||||||
|
if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove plugin options.
|
||||||
|
*/
|
||||||
|
delete_option( 'maple_icons_settings' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove transients.
|
||||||
|
*/
|
||||||
|
global $wpdb;
|
||||||
|
$wpdb->query(
|
||||||
|
"DELETE FROM {$wpdb->options} WHERE option_name LIKE '_transient_mi_%' OR option_name LIKE '_transient_timeout_mi_%'"
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove downloaded icons directory.
|
||||||
|
*/
|
||||||
|
$icons_dir = WP_CONTENT_DIR . '/maple-icons/';
|
||||||
|
|
||||||
|
if ( is_dir( $icons_dir ) ) {
|
||||||
|
/**
|
||||||
|
* Recursively delete a directory and its contents.
|
||||||
|
*
|
||||||
|
* @param string $dir Directory path.
|
||||||
|
* @return bool True on success, false on failure.
|
||||||
|
*/
|
||||||
|
function mi_delete_directory( $dir ) {
|
||||||
|
if ( ! is_dir( $dir ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$files = array_diff( scandir( $dir ), array( '.', '..' ) );
|
||||||
|
|
||||||
|
foreach ( $files as $file ) {
|
||||||
|
$path = $dir . '/' . $file;
|
||||||
|
|
||||||
|
if ( is_dir( $path ) ) {
|
||||||
|
mi_delete_directory( $path );
|
||||||
|
} else {
|
||||||
|
unlink( $path );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rmdir( $dir );
|
||||||
|
}
|
||||||
|
|
||||||
|
mi_delete_directory( $icons_dir );
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue