feat: replace all form BooleanFields with PrimitiveCheckboxWidget via mixin
This commit is contained in:
@@ -209,9 +209,6 @@ textarea:disabled {
|
|||||||
input:not([type="checkbox"]):not([data-search-select-search]) {
|
input:not([type="checkbox"]):not([data-search-select-search]) {
|
||||||
@apply mb-3 bg-neutral-secondary-medium border border-default-medium text-heading text-sm rounded-base focus:ring-brand focus:border-brand block w-full px-3 py-2.5 shadow-xs placeholder:text-body;
|
@apply mb-3 bg-neutral-secondary-medium border border-default-medium text-heading text-sm rounded-base focus:ring-brand focus:border-brand block w-full px-3 py-2.5 shadow-xs placeholder:text-body;
|
||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
|
||||||
@apply w-4 h-4 border border-default-medium rounded-xs bg-neutral-secondary-medium focus:ring-2 focus:ring-brand-soft;
|
|
||||||
}
|
|
||||||
select {
|
select {
|
||||||
@apply w-full px-3 py-2.5 bg-neutral-secondary-medium border border-default-medium text-heading text-sm rounded-base focus:ring-brand focus:border-brand shadow-xs placeholder:text-body;
|
@apply w-full px-3 py-2.5 bg-neutral-secondary-medium border border-default-medium text-heading text-sm rounded-base focus:ring-brand focus:border-brand shadow-xs placeholder:text-body;
|
||||||
}
|
}
|
||||||
|
|||||||
+35
-7
@@ -8,6 +8,7 @@ from common.components import (
|
|||||||
SearchSelectOption,
|
SearchSelectOption,
|
||||||
searchselect_selected,
|
searchselect_selected,
|
||||||
)
|
)
|
||||||
|
from common.components.primitives import Checkbox
|
||||||
from games.models import (
|
from games.models import (
|
||||||
Device,
|
Device,
|
||||||
Game,
|
Game,
|
||||||
@@ -25,6 +26,33 @@ custom_datetime_widget = forms.DateTimeInput(
|
|||||||
autofocus_input_widget = forms.TextInput(attrs={"autofocus": "autofocus"})
|
autofocus_input_widget = forms.TextInput(attrs={"autofocus": "autofocus"})
|
||||||
|
|
||||||
|
|
||||||
|
class PrimitiveCheckboxWidget(forms.CheckboxInput):
|
||||||
|
"""Adapts Django's CheckboxInput to use our Checkbox component."""
|
||||||
|
def render(self, name, value, attrs=None, renderer=None):
|
||||||
|
final_attrs = self.build_attrs(self.attrs, attrs)
|
||||||
|
checked = self.check_test(value)
|
||||||
|
attributes = [(k, str(v)) for k, v in final_attrs.items() if k not in ("type", "name", "value", "checked")]
|
||||||
|
|
||||||
|
# Django uses boolean values differently for checkboxes, we omit value if empty
|
||||||
|
return str(Checkbox(
|
||||||
|
name=name,
|
||||||
|
label=None,
|
||||||
|
checked=checked,
|
||||||
|
value=str(value) if value else "1",
|
||||||
|
attributes=attributes
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
|
class PrimitiveWidgetsMixin:
|
||||||
|
"""Automatically applies primitive custom widgets to native Django form fields."""
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
for field_name, field in self.fields.items():
|
||||||
|
if isinstance(field, forms.BooleanField):
|
||||||
|
field.widget = PrimitiveCheckboxWidget()
|
||||||
|
# Maintain the field's explicit required status (usually False for booleans)
|
||||||
|
|
||||||
|
|
||||||
class MultipleGameChoiceField(forms.ModelMultipleChoiceField):
|
class MultipleGameChoiceField(forms.ModelMultipleChoiceField):
|
||||||
def label_from_instance(self, obj) -> str:
|
def label_from_instance(self, obj) -> str:
|
||||||
return obj.search_label
|
return obj.search_label
|
||||||
@@ -128,7 +156,7 @@ class SearchSelectMultiple(SearchSelectWidget):
|
|||||||
return data.get(name)
|
return data.get(name)
|
||||||
|
|
||||||
|
|
||||||
class SessionForm(forms.ModelForm):
|
class SessionForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
game = SingleGameChoiceField(
|
game = SingleGameChoiceField(
|
||||||
queryset=Game.objects.order_by("sort_name"),
|
queryset=Game.objects.order_by("sort_name"),
|
||||||
widget=SearchSelectWidget(
|
widget=SearchSelectWidget(
|
||||||
@@ -212,7 +240,7 @@ class RelatedPurchaseChoiceField(forms.ModelChoiceField):
|
|||||||
return name or obj.standardized_name
|
return name or obj.standardized_name
|
||||||
|
|
||||||
|
|
||||||
class PurchaseForm(forms.ModelForm):
|
class PurchaseForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.fields["platform"].queryset = Platform.objects.order_by("name")
|
self.fields["platform"].queryset = Platform.objects.order_by("name")
|
||||||
@@ -305,7 +333,7 @@ class GameModelChoiceField(forms.ModelChoiceField):
|
|||||||
return obj.sort_name
|
return obj.sort_name
|
||||||
|
|
||||||
|
|
||||||
class GameForm(forms.ModelForm):
|
class GameForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
platform = forms.ModelChoiceField(
|
platform = forms.ModelChoiceField(
|
||||||
queryset=Platform.objects.order_by("name"),
|
queryset=Platform.objects.order_by("name"),
|
||||||
required=False,
|
required=False,
|
||||||
@@ -329,7 +357,7 @@ class GameForm(forms.ModelForm):
|
|||||||
widgets = {"name": autofocus_input_widget}
|
widgets = {"name": autofocus_input_widget}
|
||||||
|
|
||||||
|
|
||||||
class PlatformForm(forms.ModelForm):
|
class PlatformForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Platform
|
model = Platform
|
||||||
fields = [
|
fields = [
|
||||||
@@ -340,14 +368,14 @@ class PlatformForm(forms.ModelForm):
|
|||||||
widgets = {"name": autofocus_input_widget}
|
widgets = {"name": autofocus_input_widget}
|
||||||
|
|
||||||
|
|
||||||
class DeviceForm(forms.ModelForm):
|
class DeviceForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Device
|
model = Device
|
||||||
fields = ["name", "type"]
|
fields = ["name", "type"]
|
||||||
widgets = {"name": autofocus_input_widget}
|
widgets = {"name": autofocus_input_widget}
|
||||||
|
|
||||||
|
|
||||||
class PlayEventForm(forms.ModelForm):
|
class PlayEventForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
game = SingleGameChoiceField(
|
game = SingleGameChoiceField(
|
||||||
queryset=Game.objects.order_by("sort_name"),
|
queryset=Game.objects.order_by("sort_name"),
|
||||||
widget=SearchSelectWidget(
|
widget=SearchSelectWidget(
|
||||||
@@ -382,7 +410,7 @@ class PlayEventForm(forms.ModelForm):
|
|||||||
return session
|
return session
|
||||||
|
|
||||||
|
|
||||||
class GameStatusChangeForm(forms.ModelForm):
|
class GameStatusChangeForm(PrimitiveWidgetsMixin, forms.ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = GameStatusChange
|
model = GameStatusChange
|
||||||
fields = [
|
fields = [
|
||||||
|
|||||||
@@ -293,85 +293,26 @@
|
|||||||
--leading-5: 20px;
|
--leading-5: 20px;
|
||||||
--radius-base: 12px;
|
--radius-base: 12px;
|
||||||
--color-body: var(--color-gray-600);
|
--color-body: var(--color-gray-600);
|
||||||
--color-body-subtle: var(--color-gray-500);
|
|
||||||
--color-heading: var(--color-gray-900);
|
--color-heading: var(--color-gray-900);
|
||||||
--color-fg-brand-subtle: var(--color-blue-200);
|
|
||||||
--color-fg-brand: var(--color-blue-700);
|
--color-fg-brand: var(--color-blue-700);
|
||||||
--color-fg-brand-strong: var(--color-blue-900);
|
|
||||||
--color-fg-success: var(--color-emerald-700);
|
|
||||||
--color-fg-success-strong: var(--color-emerald-900);
|
|
||||||
--color-fg-danger: var(--color-rose-700);
|
|
||||||
--color-fg-danger-strong: var(--color-rose-900);
|
|
||||||
--color-fg-warning-subtle: var(--color-orange-600);
|
|
||||||
--color-fg-warning: var(--color-orange-900);
|
|
||||||
--color-fg-yellow: var(--color-yellow-400);
|
|
||||||
--color-fg-disabled: var(--color-gray-400);
|
--color-fg-disabled: var(--color-gray-400);
|
||||||
--color-fg-purple: var(--color-purple-600);
|
|
||||||
--color-fg-cyan: var(--color-cyan-600);
|
|
||||||
--color-fg-indigo: var(--color-indigo-600);
|
|
||||||
--color-fg-pink: var(--color-pink-600);
|
|
||||||
--color-fg-lime: var(--color-lime-600);
|
|
||||||
--color-neutral-primary-soft: var(--color-white);
|
--color-neutral-primary-soft: var(--color-white);
|
||||||
--color-neutral-primary: var(--color-white);
|
--color-neutral-primary: var(--color-white);
|
||||||
--color-neutral-primary-medium: var(--color-white);
|
--color-neutral-primary-medium: var(--color-white);
|
||||||
--color-neutral-primary-strong: var(--color-white);
|
|
||||||
--color-neutral-secondary-soft: var(--color-gray-50);
|
--color-neutral-secondary-soft: var(--color-gray-50);
|
||||||
--color-neutral-secondary: var(--color-gray-50);
|
--color-neutral-secondary: var(--color-gray-50);
|
||||||
--color-neutral-secondary-medium: var(--color-gray-50);
|
--color-neutral-secondary-medium: var(--color-gray-50);
|
||||||
--color-neutral-secondary-strong: var(--color-gray-50);
|
--color-neutral-secondary-strong: var(--color-gray-50);
|
||||||
--color-neutral-secondary-strongest: var(--color-gray-50);
|
|
||||||
--color-neutral-tertiary-soft: var(--color-gray-100);
|
|
||||||
--color-neutral-tertiary: var(--color-gray-100);
|
--color-neutral-tertiary: var(--color-gray-100);
|
||||||
--color-neutral-tertiary-medium: var(--color-gray-100);
|
--color-neutral-tertiary-medium: var(--color-gray-100);
|
||||||
--color-neutral-quaternary: var(--color-gray-200);
|
--color-neutral-quaternary: var(--color-gray-200);
|
||||||
--color-neutral-quaternary-medium: var(--color-gray-200);
|
|
||||||
--color-gray: var(--color-gray-300);
|
|
||||||
--color-brand-softer: var(--color-blue-50);
|
|
||||||
--color-brand-soft: var(--color-blue-100);
|
|
||||||
--color-brand: var(--color-blue-700);
|
--color-brand: var(--color-blue-700);
|
||||||
--color-brand-medium: var(--color-blue-200);
|
--color-brand-medium: var(--color-blue-200);
|
||||||
--color-brand-strong: var(--color-blue-800);
|
--color-brand-strong: var(--color-blue-800);
|
||||||
--color-success-soft: var(--color-emerald-50);
|
|
||||||
--color-success: var(--color-emerald-700);
|
|
||||||
--color-success-medium: var(--color-emerald-100);
|
|
||||||
--color-success-strong: var(--color-emerald-800);
|
|
||||||
--color-danger-soft: var(--color-rose-50);
|
|
||||||
--color-danger: var(--color-rose-700);
|
|
||||||
--color-danger-medium: var(--color-rose-100);
|
|
||||||
--color-danger-strong: var(--color-rose-800);
|
|
||||||
--color-warning-soft: var(--color-orange-50);
|
|
||||||
--color-warning: var(--color-orange-500);
|
|
||||||
--color-warning-medium: var(--color-orange-100);
|
|
||||||
--color-warning-strong: var(--color-orange-700);
|
|
||||||
--color-dark-soft: var(--color-gray-800);
|
|
||||||
--color-dark: var(--color-gray-800);
|
--color-dark: var(--color-gray-800);
|
||||||
--color-dark-strong: var(--color-gray-900);
|
|
||||||
--color-disabled: var(--color-gray-100);
|
|
||||||
--color-purple: var(--color-purple-500);
|
|
||||||
--color-sky: var(--color-sky-500);
|
|
||||||
--color-teal: var(--color-teal-600);
|
|
||||||
--color-pink: var(--color-pink-600);
|
|
||||||
--color-cyan: var(--color-cyan-500);
|
|
||||||
--color-fuchsia: var(--color-fuchsia-600);
|
|
||||||
--color-indigo: var(--color-indigo-600);
|
|
||||||
--color-orange: var(--color-orange-400);
|
|
||||||
--color-buffer: var(--color-white);
|
|
||||||
--color-buffer-medium: var(--color-white);
|
|
||||||
--color-buffer-strong: var(--color-white);
|
|
||||||
--color-muted: var(--color-gray-50);
|
|
||||||
--color-light-subtle: var(--color-gray-100);
|
|
||||||
--color-light: var(--color-gray-100);
|
--color-light: var(--color-gray-100);
|
||||||
--color-light-medium: var(--color-gray-100);
|
|
||||||
--color-default-subtle: var(--color-gray-200);
|
|
||||||
--color-default: var(--color-gray-200);
|
--color-default: var(--color-gray-200);
|
||||||
--color-default-medium: var(--color-gray-200);
|
--color-default-medium: var(--color-gray-200);
|
||||||
--color-default-strong: var(--color-gray-200);
|
|
||||||
--color-success-subtle: var(--color-emerald-200);
|
|
||||||
--color-danger-subtle: var(--color-rose-200);
|
|
||||||
--color-warning-subtle: var(--color-orange-200);
|
|
||||||
--color-brand-subtle: var(--color-blue-200);
|
|
||||||
--color-brand-light: var(--color-blue-600);
|
|
||||||
--color-dark-subtle: var(--color-gray-800);
|
|
||||||
--color-dark-backdrop: var(--color-gray-950);
|
--color-dark-backdrop: var(--color-gray-950);
|
||||||
--color-accent: #7c3aed;
|
--color-accent: #7c3aed;
|
||||||
}
|
}
|
||||||
@@ -881,18 +822,12 @@
|
|||||||
.start-0 {
|
.start-0 {
|
||||||
inset-inline-start: calc(var(--spacing) * 0);
|
inset-inline-start: calc(var(--spacing) * 0);
|
||||||
}
|
}
|
||||||
.end-1 {
|
|
||||||
inset-inline-end: calc(var(--spacing) * 1);
|
|
||||||
}
|
|
||||||
.end-1\.5 {
|
.end-1\.5 {
|
||||||
inset-inline-end: calc(var(--spacing) * 1.5);
|
inset-inline-end: calc(var(--spacing) * 1.5);
|
||||||
}
|
}
|
||||||
.top-0 {
|
.top-0 {
|
||||||
top: calc(var(--spacing) * 0);
|
top: calc(var(--spacing) * 0);
|
||||||
}
|
}
|
||||||
.top-1 {
|
|
||||||
top: calc(var(--spacing) * 1);
|
|
||||||
}
|
|
||||||
.top-1\/2 {
|
.top-1\/2 {
|
||||||
top: calc(1 / 2 * 100%);
|
top: calc(1 / 2 * 100%);
|
||||||
}
|
}
|
||||||
@@ -914,9 +849,6 @@
|
|||||||
.bottom-0 {
|
.bottom-0 {
|
||||||
bottom: calc(var(--spacing) * 0);
|
bottom: calc(var(--spacing) * 0);
|
||||||
}
|
}
|
||||||
.bottom-1 {
|
|
||||||
bottom: calc(var(--spacing) * 1);
|
|
||||||
}
|
|
||||||
.bottom-1\.5 {
|
.bottom-1\.5 {
|
||||||
bottom: calc(var(--spacing) * 1.5);
|
bottom: calc(var(--spacing) * 1.5);
|
||||||
}
|
}
|
||||||
@@ -1629,15 +1561,9 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.w-1 {
|
|
||||||
width: calc(var(--spacing) * 1);
|
|
||||||
}
|
|
||||||
.w-1\/2 {
|
.w-1\/2 {
|
||||||
width: calc(1 / 2 * 100%);
|
width: calc(1 / 2 * 100%);
|
||||||
}
|
}
|
||||||
.w-2 {
|
|
||||||
width: calc(var(--spacing) * 2);
|
|
||||||
}
|
|
||||||
.w-2\.5 {
|
.w-2\.5 {
|
||||||
width: calc(var(--spacing) * 2.5);
|
width: calc(var(--spacing) * 2.5);
|
||||||
}
|
}
|
||||||
@@ -1755,9 +1681,6 @@
|
|||||||
.shrink-0 {
|
.shrink-0 {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
.border-collapse {
|
|
||||||
border-collapse: collapse;
|
|
||||||
}
|
|
||||||
.-translate-x-full {
|
.-translate-x-full {
|
||||||
--tw-translate-x: -100%;
|
--tw-translate-x: -100%;
|
||||||
translate: var(--tw-translate-x) var(--tw-translate-y);
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
||||||
@@ -1774,10 +1697,6 @@
|
|||||||
--tw-translate-x: 100%;
|
--tw-translate-x: 100%;
|
||||||
translate: var(--tw-translate-x) var(--tw-translate-y);
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
||||||
}
|
}
|
||||||
.-translate-y-1 {
|
|
||||||
--tw-translate-y: calc(var(--spacing) * -1);
|
|
||||||
translate: var(--tw-translate-x) var(--tw-translate-y);
|
|
||||||
}
|
|
||||||
.-translate-y-1\/2 {
|
.-translate-y-1\/2 {
|
||||||
--tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
|
--tw-translate-y: calc(calc(1 / 2 * 100%) * -1);
|
||||||
translate: var(--tw-translate-x) var(--tw-translate-y);
|
translate: var(--tw-translate-x) var(--tw-translate-y);
|
||||||
@@ -2169,18 +2088,12 @@
|
|||||||
.bg-amber-50 {
|
.bg-amber-50 {
|
||||||
background-color: var(--color-amber-50);
|
background-color: var(--color-amber-50);
|
||||||
}
|
}
|
||||||
.bg-amber-500 {
|
|
||||||
background-color: var(--color-amber-500);
|
|
||||||
}
|
|
||||||
.bg-amber-500\/15 {
|
.bg-amber-500\/15 {
|
||||||
background-color: color-mix(in srgb, oklch(76.9% 0.188 70.08) 15%, transparent);
|
background-color: color-mix(in srgb, oklch(76.9% 0.188 70.08) 15%, transparent);
|
||||||
@supports (color: color-mix(in lab, red, red)) {
|
@supports (color: color-mix(in lab, red, red)) {
|
||||||
background-color: color-mix(in oklab, var(--color-amber-500) 15%, transparent);
|
background-color: color-mix(in oklab, var(--color-amber-500) 15%, transparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bg-black {
|
|
||||||
background-color: var(--color-black);
|
|
||||||
}
|
|
||||||
.bg-black\/70 {
|
.bg-black\/70 {
|
||||||
background-color: color-mix(in srgb, #000 70%, transparent);
|
background-color: color-mix(in srgb, #000 70%, transparent);
|
||||||
@supports (color: color-mix(in lab, red, red)) {
|
@supports (color: color-mix(in lab, red, red)) {
|
||||||
@@ -2205,9 +2118,6 @@
|
|||||||
background-color: color-mix(in oklab, var(--color-brand) 15%, transparent);
|
background-color: color-mix(in oklab, var(--color-brand) 15%, transparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bg-dark-backdrop {
|
|
||||||
background-color: var(--color-dark-backdrop);
|
|
||||||
}
|
|
||||||
.bg-dark-backdrop\/70 {
|
.bg-dark-backdrop\/70 {
|
||||||
background-color: color-mix(in srgb, oklch(13% 0.028 261.692) 70%, transparent);
|
background-color: color-mix(in srgb, oklch(13% 0.028 261.692) 70%, transparent);
|
||||||
@supports (color: color-mix(in lab, red, red)) {
|
@supports (color: color-mix(in lab, red, red)) {
|
||||||
@@ -2226,18 +2136,12 @@
|
|||||||
.bg-gray-500 {
|
.bg-gray-500 {
|
||||||
background-color: var(--color-gray-500);
|
background-color: var(--color-gray-500);
|
||||||
}
|
}
|
||||||
.bg-gray-800 {
|
|
||||||
background-color: var(--color-gray-800);
|
|
||||||
}
|
|
||||||
.bg-gray-800\/20 {
|
.bg-gray-800\/20 {
|
||||||
background-color: color-mix(in srgb, oklch(27.8% 0.033 256.848) 20%, transparent);
|
background-color: color-mix(in srgb, oklch(27.8% 0.033 256.848) 20%, transparent);
|
||||||
@supports (color: color-mix(in lab, red, red)) {
|
@supports (color: color-mix(in lab, red, red)) {
|
||||||
background-color: color-mix(in oklab, var(--color-gray-800) 20%, transparent);
|
background-color: color-mix(in oklab, var(--color-gray-800) 20%, transparent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.bg-gray-900 {
|
|
||||||
background-color: var(--color-gray-900);
|
|
||||||
}
|
|
||||||
.bg-gray-900\/50 {
|
.bg-gray-900\/50 {
|
||||||
background-color: color-mix(in srgb, oklch(21% 0.034 264.665) 50%, transparent);
|
background-color: color-mix(in srgb, oklch(21% 0.034 264.665) 50%, transparent);
|
||||||
@supports (color: color-mix(in lab, red, red)) {
|
@supports (color: color-mix(in lab, red, red)) {
|
||||||
@@ -2367,18 +2271,6 @@
|
|||||||
fill: white !important;
|
fill: white !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.apexcharts-gridline {
|
|
||||||
stroke: var(--color-default) !important;
|
|
||||||
.dark & {
|
|
||||||
stroke: var(--color-default) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.apexcharts-xcrosshairs {
|
|
||||||
stroke: var(--color-default) !important;
|
|
||||||
.dark & {
|
|
||||||
stroke: var(--color-default) !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.apexcharts-ycrosshairs {
|
.apexcharts-ycrosshairs {
|
||||||
stroke: var(--color-default) !important;
|
stroke: var(--color-default) !important;
|
||||||
.dark & {
|
.dark & {
|
||||||
@@ -2437,9 +2329,6 @@
|
|||||||
.px-6 {
|
.px-6 {
|
||||||
padding-inline: calc(var(--spacing) * 6);
|
padding-inline: calc(var(--spacing) * 6);
|
||||||
}
|
}
|
||||||
.py-0 {
|
|
||||||
padding-block: calc(var(--spacing) * 0);
|
|
||||||
}
|
|
||||||
.py-0\.5 {
|
.py-0\.5 {
|
||||||
padding-block: calc(var(--spacing) * 0.5);
|
padding-block: calc(var(--spacing) * 0.5);
|
||||||
}
|
}
|
||||||
@@ -2666,9 +2555,6 @@
|
|||||||
.text-balance {
|
.text-balance {
|
||||||
text-wrap: balance;
|
text-wrap: balance;
|
||||||
}
|
}
|
||||||
.text-wrap {
|
|
||||||
text-wrap: wrap;
|
|
||||||
}
|
|
||||||
.whitespace-nowrap {
|
.whitespace-nowrap {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
@@ -2804,9 +2690,6 @@
|
|||||||
.line-through {
|
.line-through {
|
||||||
text-decoration-line: line-through;
|
text-decoration-line: line-through;
|
||||||
}
|
}
|
||||||
.no-underline {
|
|
||||||
text-decoration-line: none;
|
|
||||||
}
|
|
||||||
.no-underline\! {
|
.no-underline\! {
|
||||||
text-decoration-line: none !important;
|
text-decoration-line: none !important;
|
||||||
}
|
}
|
||||||
@@ -2873,10 +2756,6 @@
|
|||||||
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||||
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
||||||
}
|
}
|
||||||
.backdrop-filter {
|
|
||||||
-webkit-backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
||||||
backdrop-filter: var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);
|
|
||||||
}
|
|
||||||
.transition {
|
.transition {
|
||||||
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
transition-property: color, background-color, border-color, outline-color, text-decoration-color, fill, stroke, --tw-gradient-from, --tw-gradient-via, --tw-gradient-to, opacity, box-shadow, transform, translate, scale, rotate, filter, -webkit-backdrop-filter, backdrop-filter, display, content-visibility, overlay, pointer-events;
|
||||||
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
|
||||||
@@ -4533,22 +4412,6 @@ form input:disabled, select:disabled, textarea:disabled {
|
|||||||
--tw-ring-color: var(--color-brand);
|
--tw-ring-color: var(--color-brand);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
|
||||||
height: calc(var(--spacing) * 4);
|
|
||||||
width: calc(var(--spacing) * 4);
|
|
||||||
border-radius: var(--radius-xs);
|
|
||||||
border-style: var(--tw-border-style);
|
|
||||||
border-width: 1px;
|
|
||||||
border-color: var(--color-default-medium);
|
|
||||||
background-color: var(--color-neutral-secondary-medium);
|
|
||||||
&:focus {
|
|
||||||
--tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
|
|
||||||
box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
|
|
||||||
}
|
|
||||||
&:focus {
|
|
||||||
--tw-ring-color: var(--color-brand-soft);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
select {
|
select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-radius: var(--radius-base);
|
border-radius: var(--radius-base);
|
||||||
|
|||||||
@@ -852,5 +852,29 @@ class ComponentPrimitivesTest(SimpleTestCase):
|
|||||||
self.assertIn("Option A", html)
|
self.assertIn("Option A", html)
|
||||||
|
|
||||||
|
|
||||||
|
class PrimitiveWidgetsTest(SimpleTestCase):
|
||||||
|
def test_mixin_applies_widget_to_boolean_fields_only(self):
|
||||||
|
from django import forms
|
||||||
|
from games.forms import PrimitiveCheckboxWidget, PrimitiveWidgetsMixin
|
||||||
|
|
||||||
|
class DummyForm(PrimitiveWidgetsMixin, forms.Form):
|
||||||
|
agree = forms.BooleanField(required=False)
|
||||||
|
name = forms.CharField(required=False)
|
||||||
|
|
||||||
|
form = DummyForm()
|
||||||
|
self.assertIsInstance(form.fields["agree"].widget, PrimitiveCheckboxWidget)
|
||||||
|
self.assertNotIsInstance(form.fields["name"].widget, PrimitiveCheckboxWidget)
|
||||||
|
|
||||||
|
def test_primitive_checkbox_widget_renders_headless(self):
|
||||||
|
from games.forms import PrimitiveCheckboxWidget
|
||||||
|
widget = PrimitiveCheckboxWidget()
|
||||||
|
html = widget.render(name="agree", value=True)
|
||||||
|
self.assertNotIn("<label", html)
|
||||||
|
self.assertIn("<input", html)
|
||||||
|
self.assertIn('type="checkbox"', html)
|
||||||
|
self.assertIn('name="agree"', html)
|
||||||
|
self.assertIn('checked="true"', html)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|||||||
Reference in New Issue
Block a user