Skip to content

Commit 86d5711

Browse files
committed
Merge branch 'add-avatar'
2 parents 97477b9 + d7f1438 commit 86d5711

29 files changed

+301
-60
lines changed

dist/flux-lite.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/manifest.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"/flux.js": "fbde5aaf"
2+
"/flux.js": "26a5ceed"
33
}

src/FluxManager.php

+13
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,19 @@ public function forwardedAttributes($attributes, $propKeys)
120120
return $props;
121121
}
122122

123+
public function attributesAfter($prefix, $attributes, $default = [])
124+
{
125+
$newAttributes = new \Illuminate\View\ComponentAttributeBag($default);
126+
127+
foreach ($attributes->all() as $key => $value) {
128+
if (str_starts_with($key, $prefix)) {
129+
$newAttributes[substr($key, strlen($prefix))] = $value;
130+
}
131+
}
132+
133+
return $newAttributes;
134+
}
135+
123136
public function applyInset($inset, $top, $right, $bottom, $left)
124137
{
125138
if ($inset === null) return '';

stubs/resources/views/flux/avatar.blade.php

-19
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
@php
3+
$classes = Flux::classes()
4+
->add('flex isolate')
5+
->add('*:not-first:-ml-2 **:ring-white **:dark:ring-zinc-900')
6+
->add('**:data-[slot=avatar]:ring-4 **:data-[slot=avatar]:data-[size=sm]:ring-2 **:data-[slot=avatar]:data-[size=xs]:ring-2')
7+
;
8+
@endphp
9+
10+
<div {{ $attributes->class($classes) }}>
11+
{{ $slot }}
12+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
2+
3+
@props([
4+
'iconVariant' => 'solid',
5+
'initials' => null,
6+
'tooltip' => null,
7+
'circle' => null,
8+
'color' => null,
9+
'badge' => null,
10+
'name' => null,
11+
'icon' => null,
12+
'size' => 'md',
13+
'src' => null,
14+
'href' => null,
15+
'alt' => null,
16+
'as' => 'div',
17+
])
18+
19+
@php
20+
if ($name && ! $initials) {
21+
$parts = explode(' ', preg_replace('/[^a-zA-Z\s]/', '', $name));
22+
23+
if ($attributes->pluck('initials:single')) {
24+
$initials = strtoupper($parts[0][0]);
25+
} else {
26+
if (count($parts) > 1) {
27+
$initials = strtoupper($parts[0][0] . $parts[1][0]);
28+
} else {
29+
$initials = strtoupper($parts[0][0]) . strtolower($parts[0][1]);
30+
}
31+
}
32+
}
33+
34+
if ($name && $tooltip === true) {
35+
$tooltip = $name;
36+
}
37+
38+
$hasTextContent = $icon ?? $initials ?? $slot->isNotEmpty();
39+
40+
// Be careful not to change the order of these colors.
41+
// They're used in the hash function below and changing them would change actual user avatar colors that they might have grown to identify with.
42+
$colors = ['red', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose'];
43+
44+
if ($hasTextContent && $color === 'auto') {
45+
$colorSeed = $attributes->pluck('color:seed') ?? $name ?? $icon ?? $initials ?? $slot;
46+
$hash = crc32((string) $colorSeed);
47+
$color = $colors[$hash % count($colors)];
48+
}
49+
50+
$classes = Flux::classes()
51+
->add(match($size) {
52+
'xl' => '[:where(&)]:size-16 [:where(&)]:text-base',
53+
'lg' => '[:where(&)]:size-12 [:where(&)]:text-base',
54+
default => '[:where(&)]:size-10 [:where(&)]:text-sm',
55+
'sm' => '[:where(&)]:size-8 [:where(&)]:text-sm',
56+
'xs' => '[:where(&)]:size-6 [:where(&)]:text-xs',
57+
})
58+
->add($circle ? '[--avatar-radius:calc(infinity*1px)]' : match($size) {
59+
'xl' => '[--avatar-radius:var(--radius-xl)]',
60+
'lg' => '[--avatar-radius:var(--radius-lg)]',
61+
default => '[--avatar-radius:var(--radius-lg)]',
62+
'sm' => '[--avatar-radius:var(--radius-md)]',
63+
'xs' => '[--avatar-radius:var(--radius-sm)]',
64+
})
65+
->add('relative isolate flex items-center justify-center')
66+
->add('[:where(&)]:font-medium')
67+
->add('rounded-[var(--avatar-radius)]')
68+
->add($hasTextContent ? '[:where(&)]:bg-zinc-200 [:where(&)]:dark:bg-zinc-600 [:where(&)]:text-zinc-800 [:where(&)]:dark:text-white' : '')
69+
->add(match($color) {
70+
'red' => 'bg-red-200 text-red-800',
71+
'orange' => 'bg-orange-200 text-orange-800',
72+
'amber' => 'bg-amber-200 text-amber-800',
73+
'yellow' => 'bg-yellow-200 text-yellow-800',
74+
'lime' => 'bg-lime-200 text-lime-800',
75+
'green' => 'bg-green-200 text-green-800',
76+
'emerald' => 'bg-emerald-200 text-emerald-800',
77+
'teal' => 'bg-teal-200 text-teal-800',
78+
'cyan' => 'bg-cyan-200 text-cyan-800',
79+
'sky' => 'bg-sky-200 text-sky-800',
80+
'blue' => 'bg-blue-200 text-blue-800',
81+
'indigo' => 'bg-indigo-200 text-indigo-800',
82+
'violet' => 'bg-violet-200 text-violet-800',
83+
'purple' => 'bg-purple-200 text-purple-800',
84+
'fuchsia' => 'bg-fuchsia-200 text-fuchsia-800',
85+
'pink' => 'bg-pink-200 text-pink-800',
86+
'rose' => 'bg-rose-200 text-rose-800',
87+
default => '',
88+
})
89+
->add(true ? [
90+
'after:absolute after:inset-0 after:inset-ring-[1px] after:inset-ring-black/7 dark:after:inset-ring-white/10',
91+
$circle ? 'after:rounded-full' : match($size) {
92+
'xl' => 'after:rounded-xl',
93+
'lg' => 'after:rounded-lg',
94+
default => 'after:rounded-lg',
95+
'sm' => 'after:rounded-md',
96+
'xs' => 'after:rounded-sm',
97+
},
98+
] : []);
99+
100+
$iconClasses = Flux::classes()
101+
->add('opacity-75')
102+
->add(match($size) {
103+
'lg' => 'size-8',
104+
default => 'size-6',
105+
'sm' => 'size-5',
106+
'xs' => 'size-4',
107+
});
108+
109+
$badgeColor = $attributes->pluck('badge:color') ?: (is_object($badge) ? $badge?->attributes?->pluck('color') : null);
110+
$badgeCircle = $attributes->pluck('badge:circle') ?: (is_object($badge) ? $badge?->attributes?->pluck('circle') : null);
111+
$badgePosition = $attributes->pluck('badge:position') ?: (is_object($badge) ? $badge?->attributes?->pluck('position') : null);
112+
$badgeVariant = $attributes->pluck('badge:variant') ?: (is_object($badge) ? $badge?->attributes?->pluck('variant') : null);
113+
114+
$badgeClasses = Flux::classes()
115+
->add('absolute min-h-3 min-w-3 ring-[2px] ring-white dark:ring-zinc-900 z-10')
116+
->add('flex items-center justify-center tabular-nums overflow-hidden')
117+
->add('text-[.625rem] text-zinc-800 dark:text-white font-medium')
118+
->add($badgeCircle ? 'rounded-full' : 'rounded-[3px]')
119+
->add($badgeVariant === 'outline' ? [
120+
'after:absolute after:inset-[3px] after:bg-white dark:after:bg-zinc-900',
121+
$badgeCircle ? 'after:rounded-full' : 'after:rounded-[1px]',
122+
] : [])
123+
->add(match($badgePosition) {
124+
'top left' => 'top-0 left-0',
125+
'top right' => 'top-0 right-0',
126+
'bottom left' => 'bottom-0 left-0',
127+
'bottom right' => 'bottom-0 right-0',
128+
default => 'bottom-0 right-0',
129+
})
130+
->add(match($badgeColor) {
131+
'red' => 'bg-red-500 dark:bg-red-400',
132+
'orange' => 'bg-orange-500 dark:bg-orange-400',
133+
'amber' => 'bg-amber-500 dark:bg-amber-400',
134+
'yellow' => 'bg-yellow-500 dark:bg-yellow-400',
135+
'lime' => 'bg-lime-500 dark:bg-lime-400',
136+
'green' => 'bg-green-500 dark:bg-green-400',
137+
'emerald' => 'bg-emerald-500 dark:bg-emerald-400',
138+
'teal' => 'bg-teal-500 dark:bg-teal-400',
139+
'cyan' => 'bg-cyan-500 dark:bg-cyan-400',
140+
'sky' => 'bg-sky-500 dark:bg-sky-400',
141+
'blue' => 'bg-blue-500 dark:bg-blue-400',
142+
'indigo' => 'bg-indigo-500 dark:bg-indigo-400',
143+
'violet' => 'bg-violet-500 dark:bg-violet-400',
144+
'purple' => 'bg-purple-500 dark:bg-purple-400',
145+
'fuchsia' => 'bg-fuchsia-500 dark:bg-fuchsia-400',
146+
'pink' => 'bg-pink-500 dark:bg-pink-400',
147+
'rose' => 'bg-rose-500 dark:bg-rose-400',
148+
'zinc' => 'bg-zinc-400 dark:bg-zinc-300',
149+
'gray' => 'bg-zinc-400 dark:bg-zinc-300',
150+
default => 'bg-white dark:bg-zinc-900',
151+
})
152+
;
153+
154+
$label = $alt ?? $name;
155+
@endphp
156+
157+
<flux:with-tooltip :$tooltip :$attributes>
158+
<flux:button-or-link :attributes="$attributes->class($classes)->merge($circle ? ['data-circle' => 'true'] : [])" :$as :$href data-flux-avatar data-slot="avatar" data-size="{{ $size }}">
159+
<?php if ($src): ?>
160+
<img src="{{ $src }}" alt="{{ $alt ?? $name }}" class="rounded-[var(--avatar-radius)]">
161+
<?php elseif ($icon): ?>
162+
<flux:icon :name="$icon" :variant="$iconVariant" :class="$iconClasses" />
163+
<?php elseif ($hasTextContent): ?>
164+
<span class="select-none">{{ $initials ?? $slot }}</span>
165+
<?php endif; ?>
166+
167+
<?php if ($badge instanceof \Illuminate\View\ComponentSlot): ?>
168+
<div {{ $badge->attributes->class($badgeClasses) }} aria-hidden="true">{{ $badge }}</div>
169+
<?php elseif ($badge): ?>
170+
<div class="{{ $badgeClasses }}" aria-hidden="true">{{ is_string($badge) ? $badge : '' }}</div>
171+
<?php endif; ?>
172+
</flux:button-or-link>
173+
</flux:with-tooltip>

stubs/resources/views/flux/badge/close.blade.php

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
2+
13
@props([
2-
'icon' => 'x-mark',
34
'iconVariant' => 'micro',
5+
'icon' => 'x-mark',
46
])
57

68
@php

stubs/resources/views/flux/badge/index.blade.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
@php $iconTrailing = $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
2+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
3+
14
@props([
25
'iconVariant' => 'micro',
36
'iconTrailing' => null,
@@ -82,7 +85,7 @@
8285
{{ $slot }}
8386

8487
<?php if ($iconTrailing): ?>
85-
<div class="pl-1 flex items-center" data-flux-badge-icon-trailing>
88+
<div class="pl-1 flex items-center" data-flux-badge-icon:trailing>
8689
<?php if (is_string($iconTrailing)): ?>
8790
<flux:icon :icon="$iconTrailing" :variant="$iconVariant" :class="$iconClasses" />
8891
<?php else: ?>
+29-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
@props([
22
'name' => null,
33
'logo' => null,
4+
'alt' => null,
45
'href' => '/',
56
])
67

@@ -15,25 +16,37 @@
1516
@endphp
1617

1718
<?php if ($name): ?>
18-
<a href="{{ $href }}" {{ $attributes->class([ $classes, 'gap-2' ])->except('alt') }} data-flux-brand>
19-
<div class="size-6 rounded-sm overflow-hidden shrink-0">
20-
<?php if (is_string($logo)): ?>
21-
<img src="{{ $logo }}" {{ $attributes->only('alt') }} />
22-
<?php else: ?>
23-
{{ $logo ?? $slot }}
24-
<?php endif; ?>
25-
</div>
19+
<a href="{{ $href }}" {{ $attributes->class([ $classes, 'gap-2' ]) }} data-flux-brand>
20+
<?php if ($logo instanceof \Illuminate\View\ComponentSlot): ?>
21+
<div {{ $logo->attributes->class('flex items-center justify-center [:where(&)]:size-6 [:where(&)]:rounded-sm overflow-hidden shrink-0') }}>
22+
{{ $logo }}
23+
</div>
24+
<?php else: ?>
25+
<div class="flex items-center justify-center size-6 rounded-sm overflow-hidden shrink-0">
26+
<?php if ($logo): ?>
27+
<img src="{{ $logo }}" alt="{{ $alt }}" />
28+
<?php else: ?>
29+
{{ $slot }}
30+
<?php endif; ?>
31+
</div>
32+
<?php endif; ?>
2633

2734
<div class="{{ $textClasses }}">{{ $name }}</div>
2835
</a>
2936
<?php else: ?>
30-
<a href="{{ $href }}" {{ $attributes->class($classes)->except('alt') }} data-flux-brand>
31-
<div class="size-8 rounded-sm overflow-hidden shrink-0">
32-
<?php if (is_string($logo)): ?>
33-
<img src="{{ $logo }}" {{ $attributes->only('alt') }} />
34-
<?php else: ?>
35-
{{ $logo ?? $slot }}
36-
<?php endif; ?>
37-
</div>
37+
<a href="{{ $href }}" {{ $attributes->class($classes) }} data-flux-brand>
38+
<?php if ($logo instanceof \Illuminate\View\ComponentSlot): ?>
39+
<div {{ $logo->attributes->class('flex items-center justify-center [:where(&)]:size-6 [:where(&)]:rounded-sm overflow-hidden shrink-0') }}>
40+
{{ $logo }}
41+
</div>
42+
<?php else: ?>
43+
<div class="flex items-center justify-center size-6 rounded-sm overflow-hidden shrink-0">
44+
<?php if ($logo): ?>
45+
<img src="{{ $logo }}" alt="{{ $alt }}" />
46+
<?php else: ?>
47+
{{ $slot }}
48+
<?php endif; ?>
49+
</div>
50+
<?php endif; ?>
3851
</a>
3952
<?php endif; ?>

stubs/resources/views/flux/breadcrumbs/item.blade.php

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
2+
13
@props([
24
'separator' => 'chevron-right',
35
'iconVariant' => 'mini',

stubs/resources/views/flux/button-or-link.blade.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
])
1616

1717
@php
18+
1819
$hrefForCurrentDetection = str($href)->startsWith(trim(config('app.url')))
1920
? (string) str($href)->after(trim(config('app.url'), '/'))
2021
: $href;
@@ -33,7 +34,7 @@
3334
: false) : $current;
3435
@endphp
3536

36-
<?php if ($as === 'div'): ?>
37+
<?php if ($as === 'div' && ! $href): ?>
3738
<div {{ $attributes }}>
3839
{{ $slot }}
3940
</div>

stubs/resources/views/flux/button/index.blade.php

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
@php $iconTrailing = $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
2+
@php $iconLeading = $iconLeading ??= $attributes->pluck('icon:leading'); @endphp
3+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
4+
15
@props([
26
'iconTrailing' => null,
37
'variant' => 'outline',

stubs/resources/views/flux/callout/heading.blade.php

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
2+
13
@props([
24
'iconVariant' => 'mini',
35
'icon' => null,

stubs/resources/views/flux/callout/index.blade.php

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
2+
13
@props([
24
'iconVariant' => 'mini',
35
'controls' => null,
@@ -177,7 +179,7 @@
177179
;
178180
@endphp
179181

180-
<div {{ $attributes->class($classes) }} data-flux-callout>
182+
<flux:button-or-link {{ $attributes->class($classes) }} data-flux-callout>
181183
<?php if (is_string($icon) && $icon !== ''): ?>
182184
<div class="{{ $iconWrapperClasses }}">
183185
<flux:icon :icon="$icon" :variant="$iconVariant" :class="$iconClasses" />
@@ -216,4 +218,4 @@
216218
{{ $controls }}
217219
</div>
218220
<?php endif; ?>
219-
</div>
221+
</flux:button-or-link>

stubs/resources/views/flux/heading.blade.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
->add(match ($size) {
1515
'xl' => 'text-2xl [&:has(+[data-flux-subheading])]:mb-2 [[data-flux-subheading]+&]:mt-2',
1616
'lg' => 'text-base [&:has(+[data-flux-subheading])]:mb-2 [[data-flux-subheading]+&]:mt-2',
17-
'base' => 'text-sm [&:has(+[data-flux-subheading])]:mb-2 [[data-flux-subheading]+&]:mt-2',
17+
default => 'text-sm [&:has(+[data-flux-subheading])]:mb-2 [[data-flux-subheading]+&]:mt-2',
1818
})
1919
;
2020
@endphp

stubs/resources/views/flux/input/index.blade.php

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
@php $iconTrailing = $iconTrailing ??= $attributes->pluck('icon:trailing'); @endphp
2+
@php $iconLeading = $iconLeading ??= $attributes->pluck('icon:leading'); @endphp
3+
@php $iconVariant = $iconVariant ??= $attributes->pluck('icon:variant'); @endphp
4+
15
@props([
26
'name' => $attributes->whereStartsWith('wire:model')->first(),
37
'iconVariant' => 'mini',

0 commit comments

Comments
 (0)