goetzrobin / spartan

Cutting-edge tools powering Angular full-stack development.
https://spartan.ng
MIT License
1.13k stars 123 forks source link

How it's "headless" and the components uses twilight css? #161

Closed jon9090 closed 4 months ago

jon9090 commented 4 months ago

How it's "headless" and the components uses twilight css? headless mean component without styles.

goetzrobin commented 4 months ago

Hey there! All spartan/ui components have two parts. The brain which takes care of functionality and a11y and the helm(et), which adds tailwind based styles. The brain packages are all headless. Helm is added on top using tailwind.

We need to improve the documentation and there's a discussion on how to do this: https://github.com/goetzrobin/spartan/discussions/107

But you can simply download the npm package of whatever component you're looking add and add styling yourself!

Let me know if this helps!

jon9090 commented 4 months ago

@goetzrobin, I understand now. Thank you for the explanation. So, if I want to utilize a combobox without any predefined styles, I should refer to your source code and replicate it in my project, customizing the styling as needed, correct?

goetzrobin commented 4 months ago

So should be able to adopt the following code to make it work with your prpject:

        <brn-popover [state]="state()" (stateChanged)="stateChanged($event)" sideOffset="5" closeDelay="100">
            <button
                class="w-[200px] justify-between"
                id="edit-profile"
                variant="outline"
                brnPopoverTrigger
                (click)="state.set('open')"
            >
                Select Framework
            </button>
            <brn-cmd *brnPopoverContent="let ctx">
                    <input placeholder="Search framework..." brnCmdInput/>
                <div *brnCmdEmpty>No results found.</div>
                <brn-cmd-list>
                    <brn-cmd-group>
                        @for (framework of frameworks; track framework) {
                            <button brnCmdItem [value]="framework.value" (selected)="commandSelected(framework)">
                            </button>
                        }
                    </brn-cmd-group>
                </brn-cmd-list>
            </brn-cmd>
        </brn-popover>

Then add styling through your own CSS

jon9090 commented 4 months ago

Thank you @goetzrobin !

One more question, I notice that when I run the nx command to generate the libs then it generate a code that diffrent from what is in the source code.

For example for accordion it generate:

import { Component, Input, computed, signal } from '@angular/core';
import { hlm } from '@spartan-ng/ui-core';
import { ClassValue } from 'clsx';

@Component({
    selector: 'hlm-accordion-icon',
    standalone: true,
    template: `
        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M19.5 8.25l-7.5 7.5-7.5-7.5" />
        </svg>
    `,
    host: {
        '[class]': '_computedClass()',
    },
})
export class HlmAccordionIconComponent {
    private readonly _userCls = signal<ClassValue>('');
    @Input()
    set class(userCls: ClassValue) {
        this._userCls.set(userCls);
    }

    protected _computedClass = computed(() => this._generateClass());
    private _generateClass() {
        return hlm('inline-block h-4 w-4 transition-transform duration-200', this._userCls());
    }
}

In the docs say:

  <div hlmAccordionItem>
                <button hlmAccordionTrigger>
                    Is it accessible?
                    <hlm-icon hlmAccIcon />
                </button>
                <brn-accordion-content hlm>Yes. It adheres to the WAI-ARIA design pattern.</brn-accordion-content>
            </div

hlm-icon is not exist in the nx generator only in the source code:

import { computed, Directive, inject, input } from '@angular/core';
import { radixChevronDown } from '@ng-icons/radix-icons';
import { hlm } from '@spartan-ng/ui-core';
import { HlmIconComponent, provideIcons } from '@spartan-ng/ui-icon-helm';
import { ClassValue } from 'clsx';

@Directive({
    selector: 'hlm-icon[hlmAccordionIcon], hlm-icon[hlmAccIcon]',
    standalone: true,
    providers: [provideIcons({ radixChevronDown })],
    host: {
        '[class]': '_computedClass()',
    },
})
export class HlmAccordionIconDirective {
    private readonly _hlmIcon = inject(HlmIconComponent);

    private readonly _userClass = input<ClassValue>('', { alias: 'class' });
    protected _computedClass = computed(() =>
        hlm('inline-block h-4 w-4 transition-transform duration-200', this._userClass()),
    );

    constructor() {
        this._hlmIcon.name = 'radixChevronDown';
    }
}

It possible the npm packages not published yet? can you fix that issue please?

goetzrobin commented 4 months ago

Yes you're right actually! We're working on releasing the newest alpha by the end of the weekend!

Thanks for pointing that out! We should probably move to automated releases or figure out a way to only deploy the docs with new releases

jon9090 commented 4 months ago

Thank you @goetzrobin for developing this library! I'm eager to utilize it in my project and eagerly await its release.

jon9090 commented 4 months ago

Hey @goetzrobin one more question please.

I copy the source code from the repo to my project:

image

Should I also copy the "brain"? or use it from the npmjs repo like this code:

import { BrnAccordionContentComponent } from '@spartan-ng/ui-accordion-brain';
import { hlm } from '@spartan-ng/ui-core';
import { ClassValue } from 'clsx';
goetzrobin commented 4 months ago

You’d install this from npm!