Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
6221b51
wip
CharrafiMed Jan 12, 2026
683bbf7
wip on skeleton docs
CharrafiMed Jan 12, 2026
e7be8ed
complete skeleton docs
CharrafiMed Jan 12, 2026
fd4a0d2
add empty state component docs
CharrafiMed Jan 14, 2026
8a6e973
wip on empty docs
CharrafiMed Jan 14, 2026
759549d
complete the empty component docs
CharrafiMed Jan 14, 2026
2e7975b
wip
CharrafiMed Jan 14, 2026
8310497
wip
CharrafiMed Jan 17, 2026
0d8a981
wip on data tables docs
CharrafiMed Jan 17, 2026
b5a6cfe
pagination docs in progress...
CharrafiMed Jan 18, 2026
4c4db82
finish pagination docs
CharrafiMed Jan 18, 2026
0f130a1
document new dropdown features: checkbox, radio variants, readOnly it…
CharrafiMed Jan 21, 2026
d0a093d
wip
CharrafiMed Jan 22, 2026
a5cba62
wip
CharrafiMed Jan 22, 2026
6df8119
wip
CharrafiMed Jan 22, 2026
7324f3e
wip
CharrafiMed Jan 22, 2026
c2523e2
wip
CharrafiMed Jan 22, 2026
3c22cb2
wip
CharrafiMed Jan 22, 2026
ae02594
wip
CharrafiMed Jan 22, 2026
984f733
wip
CharrafiMed Jan 22, 2026
4dc9155
doing some really progress on data table docs*...
CharrafiMed Jan 22, 2026
97e1f83
wip
CharrafiMed Jan 23, 2026
60f832d
add clumn visibilty docs
CharrafiMed Jan 23, 2026
1c15427
wip
CharrafiMed Jan 23, 2026
908aad7
complete current data table implementation docs
CharrafiMed Jan 23, 2026
43c434e
wip
CharrafiMed Jan 23, 2026
51d976b
wip
CharrafiMed Jan 23, 2026
bafd6a0
wip
CharrafiMed Jan 23, 2026
0f5319a
fix dragging sot issue docs
CharrafiMed Jan 23, 2026
7a0c8af
add reorder docs
CharrafiMed Jan 23, 2026
b92ad3a
add re ordering to the guide
CharrafiMed Jan 23, 2026
c51b995
wip
CharrafiMed Jan 23, 2026
86277a4
sync button changes
CharrafiMed Jan 25, 2026
09e7191
sync checkbox changes
CharrafiMed Jan 25, 2026
a999d00
sync dropdown changes
CharrafiMed Jan 25, 2026
3f326d4
upload new empty component files and config
CharrafiMed Jan 25, 2026
c41bfa8
sync input changes
CharrafiMed Jan 25, 2026
df8b3e6
sync select changes
CharrafiMed Jan 25, 2026
c2f65ab
upload new skeleton component files and config
CharrafiMed Jan 25, 2026
d0cf794
fix color bug && sync changes
CharrafiMed Jan 25, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 8 additions & 9 deletions components/button/files/index.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
$sizeClasses = match($size) {
'lg' => '[:where(&)]:h-12 text-md' . ' '. ( $squared ? 'w-12': ($icon ? 'ps-4' : 'ps-5') . ' ' . ($iconAfter ? 'pe-4' : 'pe-5')),
'md' => '[:where(&)]:h-10 text-base' . ' '. ( $squared ? 'w-10': ($icon ? 'ps-3' : 'ps-4') . ' ' . ($iconAfter ? 'pe-3' : 'pe-4')), // default
'sm' => '[:where(&)]:h-8 text-sm' . ' '. ( $squared ? 'w-8': ($icon ? 'ps-2' : 'ps-3') . ' ' . ($iconAfter ? 'pe-2' : 'pe-3')),
'sm' => '[:where(&)]:h-9 text-sm' . ' '. ( $squared ? 'w-9': ($icon ? 'ps-2' : 'ps-3') . ' ' . ($iconAfter ? 'pe-2' : 'pe-3')),
'xs' => '[:where(&)]:h-6 text-xs' . ' '. ( $squared ? 'w-6': ($icon ? 'ps-1' : 'ps-2') . ' ' . ($iconAfter ? 'pe-1' : 'pe-2')),
default => '[:where(&)]:h-10 text-sm' . ' '. ( $squared ? 'w-10': ($icon ? 'ps-3' : 'ps-4') . ' ' . ($iconAfter ? 'pe-3' : 'pe-4')),
};
Expand Down Expand Up @@ -82,7 +82,7 @@
// Determine variant-specific classes for background, text, borders, and hover states
$variantClasses = match($variant){
'primary' => [
'bg-[var(--color-primary)] hover:bg-[--alpha(var(--color-primary)/50%)', // Background color
'bg-[var(--color-primary)] hover:bg-[var(--color-primary)]/90', // Background color
'text-[var(--color-primary-fg)]', // Text color
'border border-black/10 dark:border-0', // Border styles
$colors => filled($color)
Expand All @@ -96,13 +96,13 @@
' bg-transparent'
],
'outline' => [
'border border-[--alpha(var(--color-primary)/50%)] hover:border-[color-mix(in_oklab,_var(--color-primary),_black_20%)]', // Border
'bg-[--alpha(var(--color-primary)/5%)] hover:bg-[--alpha(var(--color-primary)/10%)]', // Background
'border border-[--alpha(var(--color-primary)/20%)] hover:border-[--alpha(var(--color-primary)/25%)]', // Border
'bg-[--alpha(var(--color-primary)/5%)] hover:bg-[--alpha(var(--color-primary)/7%)]', // Background
'text-[var(--color-primary)]',
$colors => filled($color), // Ensure variables are set
],
'ghost' => [
'bg-transparent hover:bg-neutral-800/5 dark:hover:bg-white/15', // Background colors
'bg-transparent hover:bg-[--alpha(var(--color-neutral-900)/5%)] dark:hover:bg-[--alpha(var(--color-white)/5%)]', // Background colors
'text-neutral-800 dark:text-white' // Text colors
],
'danger' =>[
Expand All @@ -116,11 +116,10 @@

// Assemble base button classes, including layout, disabled states, and conditional styles
$classes = [
'relative inline-flex items-center font-medium justify-center gap-x-2 whitespace-nowrap transition-colors duration-200',
'[contain:layout]', // fix for chrome bug with loading: nothing outside effect this internal layout,
'relative [:where(&)]:inline-flex items-center font-medium justify-center gap-x-2 whitespace-nowrap transition-colors duration-200',
'disabled:opacity-55 dark:disabled:opacity-55 disabled:cursor-default disabled:pointer-events-none cursor-pointer',
'[&_a]:no-underline [&_a]:decoration-none [&_a:hover]:no-underline' => $variant !== 'none' , // Handle anchor tags inside the button
'rounded-field' => $variant !== 'none' , // Apply rounding unless variant is 'none'
'[:where(&)]:rounded-field' => $variant !== 'none' , // Apply rounding unless variant is 'none'

// Handling loading logic via CSS: Show loading indicator as flex and set opacity-0 on its siblings
'[&>[data-loading=true]:first-child]:flex', // Override 'hidden' to display the loading div during loading
Expand Down Expand Up @@ -177,7 +176,7 @@
@endif

@if($slot->isNotEmpty())
<span >
<span data-text>
{{ $slot }}
</span>
@endif
Expand Down
5 changes: 0 additions & 5 deletions components/checkbox/files/index.blade.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
{{--
Custom checkbox component that handles both individual and group states
Supports Livewire and Alpine.js model binding with automatic state synchronization
--}}

@aware([
'variant' => 'default'
])
Expand Down
1 change: 1 addition & 0 deletions components/dropdown/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ files:
item: resources/views/components/ui/dropdown/item.blade.php
submenu: resources/views/components/ui/dropdown/submenu.blade.php
group: resources/views/components/ui/dropdown/group.blade.php
checkbox-or-radio: resources/views/components/ui/dropdown/checkbox-or-radio.blade.php
separator: resources/views/components/ui/dropdown/separator.blade.php
dependencies:
internal: [icon]
106 changes: 106 additions & 0 deletions components/dropdown/files/checkbox-or-radio.blade.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
@aware([
'radio'=> false,
'checkbox' => false,
'disabled' => false,
'name' => null,
'checkboxVariant' => false,
'icon' => null,
'shortcut' => null
])

<!-- prevent those props from been part of the attributes bag... -->
@props([
'classes' => '',
'value' => '',
'iconClasses' => ''
])

@php
$role = $checkbox ? 'menuitemcheckbox' : 'menuitemradio';

@endphp


<label
{{ $attributes
->whereDoesntStartWith(['wire:model', 'x-model'])
->class(Arr::toCssClasses($classes))
}}
role="{{ $role }}"
aria-disabled="{{ $disabled ? 'true' : 'false' }}"
data-slot="dropdown-item"
x-data="{ checked: false }"
x-init="queueMicrotask(() => checked = $refs.input.checked)"
x-bind:aria-checked="checked"
x-on:keydown.enter.prevent.stop="$refs.input.click()"
x-on:keydown.space.prevent.stop="$refs.input.click()"
>
<input
type="{{ $checkbox ? 'checkbox' : 'radio' }}"
{{ $attributes->whereStartsWith(['wire:model', 'x-model']) }}
value="{{ $value }}"
x-ref="input"
x-on:click="checked = !checked"
@if ($name) name="{{ $name }}" @endif
@disabled($disabled)
class="peer sr-only"
/>

@if ($checkboxVariant)
<div class="relative inline-grid place-items-center size-5 mr-2">
{{-- Checkbox background --}}
<span
class="
size-4.5 rounded ring-1
ring-neutral-100 dark:ring-white/10
transition shadow
"
x-bind:class="{
'ring-2 bg-[var(--color-primary)]': checked,
'ring-1': !checked
}"
></span>
<x-ui.icon
name="check"
class="
absolute size-4 text-(--color-primary-fg)!
transition-all duration-200
"
x-bind:class="{
'opacity-100 scale-100': checked,
'opacity-0 scale-75': !checked
}"
/>
</div>
@else
<x-ui.icon
name="check"
variant="mini"
class="{{ Arr::toCssClasses([
...$iconClasses,
'opacity-0 peer-checked:opacity-100 transition-opacity duration-150',
]) }}"
aria-hidden="true"
/>
@endif
@if (filled($icon))
<x-ui.icon
:name="$icon"
:variant="$iconVariant"
:attributes="$iconAttributes"
data-slot="right-icon"
/>
@endif

@if($slot->isNotEmpty())
<span class="col-start-3 whitespace-nowrap flex items-center justify-between gap-4">
<span>{{ $slot }}</span>

@if(filled($shortcut))
<x-ui.kbd>
{{ $shortcut }}
</x-ui.kbd>
@endif
</span>
@endif
</label>
3 changes: 1 addition & 2 deletions components/dropdown/files/group.blade.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{{-- dropdown/group.blade.php --}}
@props(['label' => null])

<div {{ $attributes->merge(['class' => 'pt-1 contents']) }}>
<div {{ $attributes->merge(['class' => 'pt-1 space-y-(--dropdown-padding) contents']) }}>
@if($label)
<div class="text-xs text-start col-span-full px-[calc(--spacing(1.5)_+_var(--dropdown-padding))] font-medium text-neutral-500 dark:text-neutral-400 tracking-wide">
{{ $label }}
Expand Down
42 changes: 32 additions & 10 deletions components/dropdown/files/index.blade.php
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
@props([
'position' => 'bottom-center',
'teleport' => 'body',
'portal' => false
'portal' => false,
'trap' => false,
'offset' => 6,
'checkbox' => false,
'radio' => false,
'resetFocus' => false
])

@php
$isDefaultDropdownVariant = $checkbox || $radio;
$classes = [
'isolate z-50',
'grid grid-cols-[auto_1fr_auto]',
'grid grid-cols-[auto_1fr_auto]' => !$isDefaultDropdownVariant ,
'grid grid-cols-[auto_auto_1fr_auto]' => $isDefaultDropdownVariant,
'[:where(&)]:max-w-96 [:where(&)]:min-w-40 text-start',
'bg-white dark:bg-neutral-900 border border-black/10 dark:border-white/10 space-y-0.5',
'rounded-(--dropdown-radius) p-(--dropdown-padding) [--dropdown-radius:var(--radius-box)] [--dropdown-padding:--spacing(.75)]',
'bg-white dark:bg-neutral-900 border border-black/10 dark:border-white/10',
'[--dropdown-radius:var(--radius-box)] [--dropdown-padding:--spacing(.75)]
rounded-(--dropdown-radius) p-(--dropdown-padding) space-y-1',
];
@endphp

<div {{ $attributes }}>
<div
x-data="{
open: false,
resetFocus:@js($resetFocus),
toggle() {
if (this.open) {
return this.close()
}

this.$refs.button.focus()
$focus.getFirst().focus()
this.open = true
},
isOpen(){
Expand All @@ -32,10 +41,11 @@
close(focusAfter) {
if (! this.open) return

this.open = false
this.open = false;

focusAfter && focusAfter.focus()
focusAfter && this.resetFocus && requestAnimationFrame(() => $focus.getFirst().focus());
},

handleFocusInOut(event) {
const panel = this.$refs.panel
const button = this.$refs.button
Expand All @@ -55,6 +65,7 @@
},

}"
wire:ignore
x-on:keydown.escape.prevent.stop="close($refs.button)"
x-on:focusin.window="handleFocusInOut($event)"
x-id="['dropdown-button']"
Expand All @@ -64,13 +75,14 @@ class="relative"
<!-- Button -->
<div
x-ref="button"
{{ $button->attributes->class('flex items-center px-2 py-1 rounded-field') }}
{{ $button->attributes }}
x-on:keydown.tab.prevent.stop="$focus.focus($focus.within($refs.panel).getFirst())"
x-on:keydown.down.prevent.stop="$focus.focus($focus.within($refs.panel).getFirst())"
x-on:keydown.space.stop.prevent="toggle()"
x-on:keydown.enter.stop.prevent="toggle()"
x-on:click="toggle()"
x-bind:aria-expanded="open"
x-bind:data-open="open"
x-bind:aria-controls="$id('dropdown-button')"
>
{{ $button }}
Expand All @@ -82,8 +94,13 @@ class="relative"

<div
x-show="open"

@if ($trap)
x-trap="open"
@endif

x-ref="panel"
x-anchor.{{ $position }}.offset.6="$refs.button"
x-anchor.{{ $position }}.offset.{{ $offset }}="$refs.button;"
x-on:keydown.down.prevent.stop="$focus.next()"
x-on:keydown.up.prevent.stop="$focus.prev()"
x-on:keydown.home.prevent.stop="$focus.first()"
Expand All @@ -98,7 +115,12 @@ class="relative"
x-transition:leave-end="opacity-0 scale-95"
x-on:click.away="close($refs.button)"
x-bind:id="$id('dropdown-button')"
style="display: none; backdrop-filter: blur(64px); -webkit-backdrop-filter: blur(64px);"
style="display: none;"
@if($radio)
role="radiogroup"
@else
role="menu"
@endif
{{ $menu->attributes->class(Arr::toCssClasses($classes)) }}
>
{{ $menu }}
Expand Down
Loading