UNPKG

@sixbell-telco/sdk

Version:

A collection of reusable components designed for use in Sixbell Telco Angular projects

327 lines (322 loc) 13.9 kB
import * as i0 from '@angular/core'; import { input, model, output, computed, Component, Host } from '@angular/core'; import { CommonModule } from '@angular/common'; import { IconComponent } from '@sixbell-telco/sdk/components/icon'; import { ClickOutsideDirective } from '@sixbell-telco/sdk/directives/click-outside'; import { cn } from '@sixbell-telco/sdk/utils/cn'; import { cva, cx } from 'class-variance-authority'; /** * @internal * Generates base dropdown button classes with style variants */ const dropdownButton = cva(['btn', 'text-pretty', 'font-medium', 'leading-normal', 'items-center', 'align-top'], { variants: { variant: { primary: ['btn-primary'], secondary: ['btn-secondary'], tertiary: ['btn-tertiary'], accent: ['btn-accent'], info: ['btn-info'], success: ['btn-success'], warning: ['btn-warning'], error: ['btn-error'], icon: [ 'btn-ghost', 'text-neutral', 'hover:text-primary', 'hover:bg-transparent', 'active:focus:bg-transparent', 'active:focus:border-transparent', 'focus-visible:outline-current', ], }, size: { xs: ['btn-xs'], sm: ['btn-sm'], md: ['btn-md'], lg: ['btn-lg'], xl: ['btn-xl'], }, iconPosition: { left: [''], right: ['flex-row-reverse'], }, }, compoundVariants: [], defaultVariants: { variant: 'secondary', size: 'md', iconPosition: 'left', }, }); /** * @internal * Generates base dropdown menu classes with positioning variants */ const dropdownMenu = cva(['dropdown'], { variants: { menuPosition: { top: ['dropdown-top'], bottom: ['dropdown-bottom'], right: ['dropdown-right'], left: ['dropdown-left'], }, menuAlignment: { start: [''], end: ['dropdown-end'], }, }, compoundVariants: [], defaultVariants: { menuPosition: 'bottom', menuAlignment: 'start', }, }); /** * @internal * Combines dropdown button and menu classes */ const dropdownComponent = ({ variant, menuAlignment, menuPosition, iconPosition } = {}) => cx(dropdownButton({ variant, iconPosition }), dropdownMenu({ menuAlignment, menuPosition })); /** * A customizable dropdown component with menu positioning and various styling options * * @remarks * Built with Tailwind CSS and class-variance-authority for style management. * Supports multiple button variants, menu positioning, and responsive behavior. * * @example * ```html * <st-dropdown * variant="primary" * menuPosition="bottom" * menuAlignment="end" * icon="chevron-down" * > * <button>Actions</button> * <div slot="menu"> * <button class="menu-item">Edit</button> * <button class="menu-item">Delete</button> * </div> * </st-dropdown> * ``` * * @example * ```html * <st-dropdown * variant="icon" * menuPosition="right" * icon="more-vertical" * > * <div slot="menu">...</div> * </st-dropdown> * ``` */ class DropdownComponent { /** * Button style variant * @defaultValue 'secondary' */ variant = input(); /** * Ghost button style (transparent background) * @defaultValue false */ ghost = input(false); /** * Outline button style (border with transparent fill) * @defaultValue false */ outline = input(false); /** * Link button style (appears as a hyperlink) * @defaultValue false */ link = input(false); /** * Soft button style (muted/subdued color variant) * @defaultValue false */ soft = input(false); /** * Dash button style (dashed border) * @defaultValue false */ dash = input(false); /** * Circular button shape * @defaultValue false */ circle = input(false); /** * Square button shape * @defaultValue false */ square = input(false); /** * Glass effect styling * @defaultValue false */ glass = input(false); /** * Button size variant * @defaultValue 'md' */ size = input(); /** * Add drop shadow * @defaultValue false */ shadow = input(false); /** * Icon name (from icon library) */ icon = input(); /** * Position of icon relative to text */ iconPosition = input(); /** * Position of dropdown menu relative to button * @defaultValue 'bottom' */ menuPosition = input('bottom'); /** * Alignment of dropdown menu content */ menuAlignment = input(); /** * Button label text */ label = input(''); /** * Controls dropdown open/close state * @defaultValue false */ isOpened = model(false); /** * Event emitted when dropdown toggle state changes */ toggled = output(); /** * @internal * Computed class string for the dropdown button */ buttonClass = computed(() => { return cn(dropdownButton({ variant: this.variant(), size: this.size(), iconPosition: this.iconPosition(), }), { 'btn-ghost': this.ghost(), 'btn-outline': this.outline(), 'btn-link': this.link(), 'btn-soft': this.soft(), 'btn-dash': this.dash(), 'btn-circle': this.circle(), 'btn-square': this.square(), glass: this.glass(), 'shadow-main': this.shadow(), }); }); /** * @internal * Computed class string for the dropdown menu container */ menuClass = computed(() => { return cn(dropdownMenu({ menuPosition: this.menuPosition(), menuAlignment: this.menuAlignment(), })); }); /** * @internal * Computed class string for the dropdown content */ dropdownContentClass = computed(() => { return cn('menu dropdown-content rounded-box bg-base-300 p-2 shadow-main', { 'mb-1': this.menuPosition() === 'top', 'mt-1': this.menuPosition() === 'bottom', 'ml-1': this.menuPosition() === 'right', 'mr-1': this.menuPosition() === 'left', }); }); /** * @internal * Toggles dropdown visibility state */ handleToggle() { this.isOpened.set(!this.isOpened()); this.toggled.emit(this.isOpened()); } /** * @internal * Handles click outside to close dropdown */ handleClickOuside() { this.isOpened.set(false); this.toggled.emit(this.isOpened()); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.0", type: DropdownComponent, isStandalone: true, selector: "st-dropdown", inputs: { variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ghost: { classPropertyName: "ghost", publicName: "ghost", isSignal: true, isRequired: false, transformFunction: null }, outline: { classPropertyName: "outline", publicName: "outline", isSignal: true, isRequired: false, transformFunction: null }, link: { classPropertyName: "link", publicName: "link", isSignal: true, isRequired: false, transformFunction: null }, soft: { classPropertyName: "soft", publicName: "soft", isSignal: true, isRequired: false, transformFunction: null }, dash: { classPropertyName: "dash", publicName: "dash", isSignal: true, isRequired: false, transformFunction: null }, circle: { classPropertyName: "circle", publicName: "circle", isSignal: true, isRequired: false, transformFunction: null }, square: { classPropertyName: "square", publicName: "square", isSignal: true, isRequired: false, transformFunction: null }, glass: { classPropertyName: "glass", publicName: "glass", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, shadow: { classPropertyName: "shadow", publicName: "shadow", isSignal: true, isRequired: false, transformFunction: null }, icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, iconPosition: { classPropertyName: "iconPosition", publicName: "iconPosition", isSignal: true, isRequired: false, transformFunction: null }, menuPosition: { classPropertyName: "menuPosition", publicName: "menuPosition", isSignal: true, isRequired: false, transformFunction: null }, menuAlignment: { classPropertyName: "menuAlignment", publicName: "menuAlignment", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isOpened: { classPropertyName: "isOpened", publicName: "isOpened", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { isOpened: "isOpenedChange", toggled: "toggled" }, ngImport: i0, template: "@let iconVar = icon();\n@let labelVar = label();\n@let isOpenedVar = isOpened();\n@let menuClassVar = menuClass();\n@let buttonClassVar = buttonClass();\n@let dropdownContentClassVar = dropdownContentClass();\n\n<details dropdown [class]=\"menuClassVar\" [attr.open]=\"isOpenedVar ? undefined : null\" stClickOutside (outsideClick)=\"handleClickOuside()\">\n\t<summary [class]=\"buttonClassVar\" (click)=\"handleToggle()\">\n\t\t@if (iconVar) {\n\t\t\t<st-icon [icon]=\"iconVar\" color=\"inherit\" size=\"auto\"></st-icon>\n\t\t}\n\t\t<div>\n\t\t\t{{ labelVar }}\n\t\t</div>\n\t</summary>\n\t<ul [class]=\"dropdownContentClassVar\">\n\t\t<ng-content></ng-content>\n\t</ul>\n</details>\n", styles: [""], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: ClickOutsideDirective, selector: "[stClickOutside]", outputs: ["outsideClick"] }, { kind: "component", type: IconComponent, selector: "st-icon", inputs: ["color", "size", "icon"] }] }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DropdownComponent, decorators: [{ type: Component, args: [{ selector: 'st-dropdown', imports: [CommonModule, ClickOutsideDirective, IconComponent], template: "@let iconVar = icon();\n@let labelVar = label();\n@let isOpenedVar = isOpened();\n@let menuClassVar = menuClass();\n@let buttonClassVar = buttonClass();\n@let dropdownContentClassVar = dropdownContentClass();\n\n<details dropdown [class]=\"menuClassVar\" [attr.open]=\"isOpenedVar ? undefined : null\" stClickOutside (outsideClick)=\"handleClickOuside()\">\n\t<summary [class]=\"buttonClassVar\" (click)=\"handleToggle()\">\n\t\t@if (iconVar) {\n\t\t\t<st-icon [icon]=\"iconVar\" color=\"inherit\" size=\"auto\"></st-icon>\n\t\t}\n\t\t<div>\n\t\t\t{{ labelVar }}\n\t\t</div>\n\t</summary>\n\t<ul [class]=\"dropdownContentClassVar\">\n\t\t<ng-content></ng-content>\n\t</ul>\n</details>\n" }] }] }); /** * A selectable item component for use within dropdown menus * * @remarks * Designed to be used inside `<st-dropdown>` components. Handles selection events * and automatically closes the parent dropdown when clicked. * * @example * ```html * <st-dropdown-item (selected)="handleItemSelect()"> * <st-icon icon="check"></st-icon> * <span typography>Select Item</span> * </st-dropdown-item> * ``` * * @example * ```html * <st-dropdown-item class="custom-item-style" (selected)="logSelection()"> * Custom styled item * </st-dropdown-item> * ``` */ class DropdownItemComponent { dropdown; /** * Event emitted when the item is selected */ selected = output(); /** * @internal * Reference to parent dropdown component */ constructor(dropdown) { this.dropdown = dropdown; } /** * @internal * Handles item selection and dropdown state */ handleSelect() { this.selected.emit(); this.dropdown.handleToggle(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DropdownItemComponent, deps: [{ token: DropdownComponent, host: true }], target: i0.ɵɵFactoryTarget.Component }); static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.0", type: DropdownItemComponent, isStandalone: true, selector: "st-dropdown-item", outputs: { selected: "selected" }, ngImport: i0, template: "<!-- eslint-disable @angular-eslint/template/click-events-have-key-events -->\n<!-- eslint-disable @angular-eslint/template/interactive-supports-focus -->\n<li (click)=\"handleSelect()\">\n\t<ng-content></ng-content>\n</li>\n" }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.0", ngImport: i0, type: DropdownItemComponent, decorators: [{ type: Component, args: [{ selector: 'st-dropdown-item', standalone: true, template: "<!-- eslint-disable @angular-eslint/template/click-events-have-key-events -->\n<!-- eslint-disable @angular-eslint/template/interactive-supports-focus -->\n<li (click)=\"handleSelect()\">\n\t<ng-content></ng-content>\n</li>\n" }] }], ctorParameters: () => [{ type: DropdownComponent, decorators: [{ type: Host }] }] }); /** * Generated bundle index. Do not edit. */ export { DropdownComponent, DropdownItemComponent, dropdownButton, dropdownComponent, dropdownMenu }; //# sourceMappingURL=sixbell-telco-sdk-components-dropdown.mjs.map