Skip to content

Commit

Permalink
improved widget (#21)
Browse files Browse the repository at this point in the history
* Updated readme

* Disabled collextions dropdown

* Handled field dark mode

* Handled django & unfokd dark mode

* Bump version to 1.0.2
  • Loading branch information
M97Chahboun authored Jan 22, 2025
1 parent 17390a0 commit b90da7f
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 65 deletions.
31 changes: 21 additions & 10 deletions django-icon-picker/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Overview

Django Icon Picker is a custom widget for Django forms that allows users to select icons from a predefined set. It supports both SVG icons and icon IDs, depending on the configuration.
Django Icon Picker is a custom Django model field that allows users to select icons from a predefined set. It supports both SVG icons and icon IDs, depending on the configuration.

## Features

Expand Down Expand Up @@ -63,17 +63,28 @@ ICON_PICKER_PATH = 'media'
ICON_PICKER_COLOR = "#00bcc9"
```

### Step 3: Override IconPicker Styling

You can override the default styling of the `IconPicker` widget by subclassing it and modifying the `attrs` dictionary in the constructor. Here's an example:
### Step 3: Use IconField on your model

```python
from typing import Any, Dict
from django_icon_picker.widgets import IconPicker

class CustomIconPicker(IconPicker):
def __init__(self, attrs: Dict[str, Any] | None = None) -> None:
super().__init__(attrs)
from django.db import models
from django_icon_picker.field import IconField
from django.utils.html import format_html

class ExampleModel(models.Model):
icon = IconField(max_length=255)
name = models.CharField(max_length=255)

def svg_icon(self):
return format_html(
'<img src="{}" height="30" width="30"/>'.format(
f"/{self.icon}"
if self.icon.endswith(".svg")
else f"https://api.iconify.design/{self.icon}.svg"
)
)

def __str__(self):
return self.icon
```

## Conclusion
Expand Down
4 changes: 3 additions & 1 deletion django-icon-picker/django_icon_picker/field.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)

def formfield(self, **kwargs):
attrs = {"model_name": self.model.__name__.lower()}
widget = kwargs.get('widget')
attrs = widget().attrs if widget else {}
attrs.update({"model_name": self.model.__name__.lower()})
kwargs["widget"] = IconPicker(attrs=attrs)
return super().formfield(**kwargs)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,60 @@
.icon-dropdown-list {
max-height: 300px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
max-height: 300px;
max-width: 300px;
overflow-y: auto;
border: 1px solid #ddd;
border-radius: 4px;
background: white;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.dark .icon-dropdown-list {
background: #333;
border: 1px solid #333;
}

[data-theme="dark"] .icon-dropdown-list {
background: #333;
border: 1px solid #333;
}

.icon-dropdown-item {
display: flex;
align-items: center;
padding: 8px 12px;
cursor: pointer;
transition: background-color 0.2s;
display: flex;
align-items: center;
padding: 8px 12px;
cursor: pointer;
transition: background-color 0.2s;
}

.icon-dropdown-item:hover {
background-color: #f5f5f5;
background-color: #f5f5f5;
}

.dark .icon-dropdown-item:hover {
background-color: #333;
}

[data-theme="dark"] .icon-dropdown-item:hover {
background-color: #333;
}

.icon-preview {
width: 24px;
height: 24px;
margin-right: 12px;
width: 24px;
height: 24px;
margin-right: 12px;
}

.icon-name {
font-size: 14px;
color: #333;
}
font-size: 14px;
color: #333;
}

.dark .icon-name {
font-size: 14px;
color: #fff;
}

[data-theme="dark"] .icon-name {
font-size: 14px;
color: #fff;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ class IconPicker {
this.searchInput = document.getElementById(options.searchInputId);
this.selectedIcon = document.getElementById("selectedIcon");
this.resultsDiv = document.getElementById("results");
this.prefixDropdown = document.getElementById("prefixDropdown");
this.colorPicker = document.getElementById("color");
this.savePath = options.savePath;
this.selectedPrefix = "";
Expand All @@ -18,7 +17,6 @@ class IconPicker {
init() {
this.setupInitialIcon();
this.setupEventListeners();
this.fetchIconifyPrefixes();
}

setupInitialIcon() {
Expand All @@ -28,10 +26,6 @@ class IconPicker {
}

setupEventListeners() {
this.prefixDropdown.addEventListener("change", (event) => {
this.selectedPrefix = event.target.value;
});

this.searchInput.addEventListener("input", () => {
const query = this.searchInput.value;
if (query.length > 2) {
Expand Down Expand Up @@ -82,7 +76,7 @@ class IconPicker {

createDropdownItem(icon, iconUrl) {
const item = document.createElement("div");
item.className = "icon-dropdown-item";
item.className = "icon-dropdown-item"

const iconImg = document.createElement("img");
iconImg.src = iconUrl;
Expand Down Expand Up @@ -111,31 +105,6 @@ class IconPicker {
return item;
}

fetchIconifyPrefixes() {
fetch("https://api.iconify.design/collections?pretty=1")
.then((response) => response.json())
.then((data) => {
const prefixes = Object.keys(data);
this.populatePrefixDropdown(prefixes);
})
.catch((error) => console.error("Error fetching icon sets:", error));
}

populatePrefixDropdown(prefixes) {
const selectElement = document.createElement("select");
selectElement.id = "prefixDropdown";
selectElement.className = "form-select block";

prefixes.forEach((prefix) => {
const option = document.createElement("option");
option.value = prefix;
option.textContent = prefix;
selectElement.appendChild(option);
});

this.prefixDropdown.appendChild(selectElement);
}

downloadAndSaveSvg(svgIcon) {
const downloadUrl = `/icon_picker/download-svg/?icon=${svgIcon}&id=${this.objectId}&model=${this.model}`;
fetch(downloadUrl)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@
<div class="icon-picker-input" style="display: flex; align-items: center;">
<img class="icon-preview" id="selectedIcon" class="{{ widget.attrs.selected_icon }}" style="margin-right: 10px;">
{% include "django/forms/widgets/text.html" %}
<div id="prefixDropdown" style="margin-left: 10px;"></div>
<input class="{{ widget.attrs.class }}" id="color" value="{{ default_color|default:"#006166" }}" type="text" data-coloris style="margin-left: 10px;">
</div>
<div id="results" class="{{ widget.attrs.result_class }}"></div>
<div id="results"></div>
</div>
</div>
<script src="{% static 'django_icon_picker/js/icon_picker.js' %}"></script>
Expand All @@ -20,7 +19,7 @@
searchInputId: "{{ widget.attrs.id }}",
savePath: "{{ save_path }}",
model: "{{ widget.attrs.model_name }}",
objectId: "{{ object_id }}"
objectId: "{{ object_id }}",
});
});
</script>
2 changes: 1 addition & 1 deletion django-icon-picker/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

setup(
name="django-icon-picker",
version="1.0.1",
version="1.0.2",
description="A custom Django model field that allows users to select icons from a predefined set.",
author="Mohammed CHAHBOUN",
author_email="[email protected]",
Expand Down

0 comments on commit b90da7f

Please sign in to comment.