@abydahana/aksara-ui 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +163 -0
- package/dist/aksara.css +33499 -0
- package/dist/aksara.d.ts +284 -0
- package/dist/aksara.esm.js +1604 -0
- package/dist/aksara.js +1608 -0
- package/dist/aksara.min.css +1 -0
- package/dist/aksara.min.js +1 -0
- package/dist/components/buttons/button-group.d.ts +10 -0
- package/dist/components/buttons/button-group.js +12 -0
- package/dist/components/buttons/button.d.ts +18 -0
- package/dist/components/buttons/button.js +28 -0
- package/dist/components/buttons/close-button.d.ts +9 -0
- package/dist/components/buttons/close-button.js +13 -0
- package/dist/components/buttons/index.d.ts +3 -0
- package/dist/components/buttons/index.js +3 -0
- package/dist/components/data/accordion.d.ts +17 -0
- package/dist/components/data/accordion.js +37 -0
- package/dist/components/data/avatar.d.ts +26 -0
- package/dist/components/data/avatar.js +64 -0
- package/dist/components/data/card.d.ts +39 -0
- package/dist/components/data/card.js +34 -0
- package/dist/components/data/carousel.d.ts +15 -0
- package/dist/components/data/carousel.js +47 -0
- package/dist/components/data/index.d.ts +7 -0
- package/dist/components/data/index.js +7 -0
- package/dist/components/data/list-group.d.ts +22 -0
- package/dist/components/data/list-group.js +30 -0
- package/dist/components/data/media-grid.d.ts +19 -0
- package/dist/components/data/media-grid.js +47 -0
- package/dist/components/data/table.d.ts +35 -0
- package/dist/components/data/table.js +30 -0
- package/dist/components/feedback/alert.d.ts +10 -0
- package/dist/components/feedback/alert.js +19 -0
- package/dist/components/feedback/badge.d.ts +13 -0
- package/dist/components/feedback/badge.js +10 -0
- package/dist/components/feedback/index.d.ts +6 -0
- package/dist/components/feedback/index.js +6 -0
- package/dist/components/feedback/placeholder.d.ts +9 -0
- package/dist/components/feedback/placeholder.js +11 -0
- package/dist/components/feedback/progress.d.ts +14 -0
- package/dist/components/feedback/progress.js +22 -0
- package/dist/components/feedback/spinner.d.ts +9 -0
- package/dist/components/feedback/spinner.js +12 -0
- package/dist/components/feedback/toast.d.ts +22 -0
- package/dist/components/feedback/toast.js +36 -0
- package/dist/components/form/checkbox.d.ts +17 -0
- package/dist/components/form/checkbox.js +29 -0
- package/dist/components/form/floating-label.d.ts +9 -0
- package/dist/components/form/floating-label.js +14 -0
- package/dist/components/form/form-control.d.ts +30 -0
- package/dist/components/form/form-control.js +28 -0
- package/dist/components/form/index.d.ts +11 -0
- package/dist/components/form/index.js +11 -0
- package/dist/components/form/input-group.d.ts +16 -0
- package/dist/components/form/input-group.js +14 -0
- package/dist/components/form/input.d.ts +18 -0
- package/dist/components/form/input.js +19 -0
- package/dist/components/form/layout.d.ts +20 -0
- package/dist/components/form/layout.js +15 -0
- package/dist/components/form/radio.d.ts +32 -0
- package/dist/components/form/radio.js +49 -0
- package/dist/components/form/range.d.ts +13 -0
- package/dist/components/form/range.js +18 -0
- package/dist/components/form/select.d.ts +25 -0
- package/dist/components/form/select.js +37 -0
- package/dist/components/form/switch.d.ts +16 -0
- package/dist/components/form/switch.js +30 -0
- package/dist/components/form/textarea.d.ts +17 -0
- package/dist/components/form/textarea.js +19 -0
- package/dist/components/index.d.ts +7 -0
- package/dist/components/index.js +7 -0
- package/dist/components/navigation/breadcrumb.d.ts +13 -0
- package/dist/components/navigation/breadcrumb.js +25 -0
- package/dist/components/navigation/index.d.ts +5 -0
- package/dist/components/navigation/index.js +5 -0
- package/dist/components/navigation/navbar.d.ts +20 -0
- package/dist/components/navigation/navbar.js +22 -0
- package/dist/components/navigation/pagination.d.ts +15 -0
- package/dist/components/navigation/pagination.js +31 -0
- package/dist/components/navigation/scrollspy.d.ts +23 -0
- package/dist/components/navigation/scrollspy.js +43 -0
- package/dist/components/navigation/tabs.d.ts +15 -0
- package/dist/components/navigation/tabs.js +56 -0
- package/dist/components/overlay/collapse.d.ts +20 -0
- package/dist/components/overlay/collapse.js +27 -0
- package/dist/components/overlay/dropdown.d.ts +33 -0
- package/dist/components/overlay/dropdown.js +41 -0
- package/dist/components/overlay/index.d.ts +7 -0
- package/dist/components/overlay/index.js +7 -0
- package/dist/components/overlay/media-modal.d.ts +15 -0
- package/dist/components/overlay/media-modal.js +83 -0
- package/dist/components/overlay/modal.d.ts +32 -0
- package/dist/components/overlay/modal.js +47 -0
- package/dist/components/overlay/offcanvas.d.ts +20 -0
- package/dist/components/overlay/offcanvas.js +33 -0
- package/dist/components/overlay/popover.d.ts +19 -0
- package/dist/components/overlay/popover.js +24 -0
- package/dist/components/overlay/tooltip.d.ts +17 -0
- package/dist/components/overlay/tooltip.js +21 -0
- package/dist/components/utils.d.ts +3 -0
- package/dist/components/utils.js +25 -0
- package/package.json +111 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { classNames, escapeHtml, toAttributes } from "../utils";
|
|
2
|
+
export function Dropdown(props = {}) {
|
|
3
|
+
const { children = "", direction, className = "", attributes } = props;
|
|
4
|
+
const classes = classNames("dropdown", direction === "up" && "dropup", direction === "end" && "dropend", direction === "start" && "dropstart", className);
|
|
5
|
+
const baseAttrs = toAttributes(attributes);
|
|
6
|
+
return `<div class="${classes}"${baseAttrs}>${children}</div>`.trim();
|
|
7
|
+
}
|
|
8
|
+
export const dropdown = Dropdown;
|
|
9
|
+
export function DropdownMenu(props = {}) {
|
|
10
|
+
const { id, children = "", end = false, dark = false, className = "", attributes } = props;
|
|
11
|
+
const classes = classNames("dropdown-menu", end && "dropdown-menu-end", dark && "dropdown-menu-dark", className);
|
|
12
|
+
const baseAttrs = toAttributes({
|
|
13
|
+
id,
|
|
14
|
+
...attributes
|
|
15
|
+
});
|
|
16
|
+
return `<div class="${classes}"${baseAttrs}>${children}</div>`.trim();
|
|
17
|
+
}
|
|
18
|
+
export const dropdownMenu = DropdownMenu;
|
|
19
|
+
export function DropdownItem(props = {}) {
|
|
20
|
+
const { content = "", href, active = false, disabled = false, danger = false, className = "", attributes } = props;
|
|
21
|
+
const Tag = href ? "a" : "button";
|
|
22
|
+
const classes = classNames("dropdown-item", active && "active", disabled && "disabled", danger && "text-danger", className);
|
|
23
|
+
const baseAttrs = toAttributes({
|
|
24
|
+
href,
|
|
25
|
+
type: Tag === "button" ? "button" : undefined,
|
|
26
|
+
disabled: disabled && Tag === "button" ? true : undefined,
|
|
27
|
+
"aria-current": active ? "true" : undefined,
|
|
28
|
+
"aria-disabled": disabled ? "true" : undefined,
|
|
29
|
+
...attributes
|
|
30
|
+
});
|
|
31
|
+
return `<${Tag} class="${classes}"${baseAttrs}>${content}</${Tag}>`.trim();
|
|
32
|
+
}
|
|
33
|
+
export const dropdownItem = DropdownItem;
|
|
34
|
+
export function DropdownDivider(className = "") {
|
|
35
|
+
return `<div class="${classNames("dropdown-divider", className)}"></div>`;
|
|
36
|
+
}
|
|
37
|
+
export const dropdownDivider = DropdownDivider;
|
|
38
|
+
export function DropdownHeader(title, className = "") {
|
|
39
|
+
return `<div class="${classNames("dropdown-header", className)}">${escapeHtml(title)}</div>`;
|
|
40
|
+
}
|
|
41
|
+
export const dropdownHeader = DropdownHeader;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface MediaPreviewModalProps {
|
|
2
|
+
id?: string;
|
|
3
|
+
items: Array<{
|
|
4
|
+
src: string;
|
|
5
|
+
alt?: string;
|
|
6
|
+
caption?: string;
|
|
7
|
+
}>;
|
|
8
|
+
activeIndex?: number;
|
|
9
|
+
sidebar?: string;
|
|
10
|
+
showZoomControls?: boolean;
|
|
11
|
+
className?: string;
|
|
12
|
+
attributes?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
export declare function MediaPreviewModal(props: MediaPreviewModalProps): string;
|
|
15
|
+
export declare const mediaPreviewModal: typeof MediaPreviewModal;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { classNames, escapeHtml, toAttributes } from "../utils";
|
|
2
|
+
export function MediaPreviewModal(props) {
|
|
3
|
+
const { id = "media-preview-modal", items = [], activeIndex = 0, sidebar, showZoomControls = true, className = "", attributes } = props;
|
|
4
|
+
const total = items.length;
|
|
5
|
+
const currentIdx = Math.max(0, Math.min(activeIndex, Math.max(0, total - 1)));
|
|
6
|
+
const currentItem = items[currentIdx] || { src: "", alt: "" };
|
|
7
|
+
const baseAttrs = toAttributes({
|
|
8
|
+
id,
|
|
9
|
+
role: "dialog",
|
|
10
|
+
"aria-modal": "true",
|
|
11
|
+
"data-active-index": currentIdx,
|
|
12
|
+
"data-total-items": total,
|
|
13
|
+
...attributes
|
|
14
|
+
});
|
|
15
|
+
const counterHtml = total > 1
|
|
16
|
+
? `
|
|
17
|
+
<div class="media-modal-counter position-absolute top-4 start-50% translate-x-[-50%] z-10 px-3 py-1 rounded-pill bg-black/60 text-white text-sm font-semibold pointer-events-none">
|
|
18
|
+
<span id="media-counter-text">${currentIdx + 1} / ${total}</span>
|
|
19
|
+
</div>
|
|
20
|
+
`.trim()
|
|
21
|
+
: "";
|
|
22
|
+
const prevBtnHtml = total > 1
|
|
23
|
+
? `
|
|
24
|
+
<button type="button" class="media-modal-btn media-modal-prev position-absolute start-4 top-50% translate-y-[-50%] z-10 w-12 h-12 rounded-full d-flex align-items-center justify-content-center border-0 bg-black/60 text-white text-xl cursor-pointer" data-media-prev aria-label="Previous media"${currentIdx === 0 ? " disabled" : ""}>
|
|
25
|
+
<span class="mdi mdi-chevron-left mdi-24px"></span>
|
|
26
|
+
</button>
|
|
27
|
+
`.trim()
|
|
28
|
+
: "";
|
|
29
|
+
const nextBtnHtml = total > 1
|
|
30
|
+
? `
|
|
31
|
+
<button type="button" class="media-modal-btn media-modal-next position-absolute end-4 top-50% translate-y-[-50%] z-10 w-12 h-12 rounded-full d-flex align-items-center justify-content-center border-0 bg-black/60 text-white text-xl cursor-pointer" data-media-next aria-label="Next media"${currentIdx === total - 1 ? " disabled" : ""}>
|
|
32
|
+
<span class="mdi mdi-chevron-right mdi-24px"></span>
|
|
33
|
+
</button>
|
|
34
|
+
`.trim()
|
|
35
|
+
: "";
|
|
36
|
+
const zoomControlsHtml = showZoomControls
|
|
37
|
+
? `
|
|
38
|
+
<div class="media-modal-zoom-controls position-absolute bottom-6 start-50% translate-x-[-50%] z-10 d-flex align-items-center gap-2 p-1 rounded-pill bg-black/70" id="media-zoom-controls">
|
|
39
|
+
<button type="button" class="media-zoom-btn w-9 h-9 rounded-full d-flex align-items-center justify-content-center border-0 bg-transparent text-white cursor-pointer" data-media-zoom-in aria-label="Zoom in" title="Zoom in">
|
|
40
|
+
<span class="mdi mdi-magnify-plus-outline mdi-18px"></span>
|
|
41
|
+
</button>
|
|
42
|
+
<button type="button" class="media-zoom-btn w-9 h-9 rounded-full d-flex align-items-center justify-content-center border-0 bg-transparent text-white cursor-pointer" data-media-zoom-out aria-label="Zoom out" title="Zoom out">
|
|
43
|
+
<span class="mdi mdi-magnify-minus-outline mdi-18px"></span>
|
|
44
|
+
</button>
|
|
45
|
+
<button type="button" class="media-zoom-btn w-9 h-9 rounded-full d-flex align-items-center justify-content-center border-0 bg-transparent text-white cursor-pointer" data-media-zoom-reset aria-label="Fit to screen" title="Fit to screen">
|
|
46
|
+
<span class="mdi mdi-fit-to-screen-outline mdi-18px"></span>
|
|
47
|
+
</button>
|
|
48
|
+
</div>
|
|
49
|
+
`.trim()
|
|
50
|
+
: "";
|
|
51
|
+
const sidebarHtml = sidebar
|
|
52
|
+
? `
|
|
53
|
+
<div class="media-modal-sidebar w-full md:w-[360px] lg:w-[420px] shrink-0 border-start border-subtle bg-body d-flex flex-col overflow-y-auto">
|
|
54
|
+
${sidebar}
|
|
55
|
+
</div>
|
|
56
|
+
`.trim()
|
|
57
|
+
: "";
|
|
58
|
+
return `
|
|
59
|
+
<div class="${classNames("media-modal-backdrop position-fixed inset-0 z-[1050] d-flex bg-black/90", className)}"${baseAttrs}>
|
|
60
|
+
<div class="media-modal-container d-flex flex-col md:flex-row w-full h-full overflow-hidden">
|
|
61
|
+
<!-- Stage -->
|
|
62
|
+
<div class="media-modal-stage flex-1 position-relative d-flex align-items-center justify-content-center overflow-hidden">
|
|
63
|
+
<button type="button" class="media-modal-btn media-modal-close position-absolute top-4 start-4 z-10 w-10 h-10 rounded-full d-flex align-items-center justify-content-center border-0 bg-black/60 text-white cursor-pointer" data-close-media-modal aria-label="Close">
|
|
64
|
+
<span class="mdi mdi-close mdi-18px"></span>
|
|
65
|
+
</button>
|
|
66
|
+
|
|
67
|
+
${counterHtml}
|
|
68
|
+
${prevBtnHtml}
|
|
69
|
+
${nextBtnHtml}
|
|
70
|
+
|
|
71
|
+
<div class="media-modal-image-wrap d-flex align-items-center justify-content-center w-full h-full p-4">
|
|
72
|
+
<img src="${escapeHtml(currentItem.src)}" id="media-modal-active-img" class="max-w-full max-h-full object-contain block transition" alt="${escapeHtml(currentItem.alt || "Preview")}" />
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
${zoomControlsHtml}
|
|
76
|
+
</div>
|
|
77
|
+
|
|
78
|
+
${sidebarHtml}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
`.trim();
|
|
82
|
+
}
|
|
83
|
+
export const mediaPreviewModal = MediaPreviewModal;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ModalProps {
|
|
2
|
+
id: string;
|
|
3
|
+
children?: string;
|
|
4
|
+
size?: "sm" | "lg" | "xl" | "fullscreen";
|
|
5
|
+
centered?: boolean;
|
|
6
|
+
scrollable?: boolean;
|
|
7
|
+
staticBackdrop?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
attributes?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare function Modal(props: ModalProps): string;
|
|
12
|
+
export declare const modal: typeof Modal;
|
|
13
|
+
export interface ModalHeaderProps {
|
|
14
|
+
title?: string;
|
|
15
|
+
children?: string;
|
|
16
|
+
dismissible?: boolean;
|
|
17
|
+
className?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function ModalHeader(props?: ModalHeaderProps): string;
|
|
20
|
+
export declare const modalHeader: typeof ModalHeader;
|
|
21
|
+
export interface ModalBodyProps {
|
|
22
|
+
children?: string;
|
|
23
|
+
className?: string;
|
|
24
|
+
}
|
|
25
|
+
export declare function ModalBody(props?: ModalBodyProps): string;
|
|
26
|
+
export declare const modalBody: typeof ModalBody;
|
|
27
|
+
export interface ModalFooterProps {
|
|
28
|
+
children?: string;
|
|
29
|
+
className?: string;
|
|
30
|
+
}
|
|
31
|
+
export declare function ModalFooter(props?: ModalFooterProps): string;
|
|
32
|
+
export declare const modalFooter: typeof ModalFooter;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { classNames, escapeHtml, toAttributes } from "../utils";
|
|
2
|
+
export function Modal(props) {
|
|
3
|
+
const { id, children = "", size, centered = false, scrollable = false, staticBackdrop = false, className = "", attributes } = props;
|
|
4
|
+
const dialogClasses = classNames("modal-dialog", size && (size === "fullscreen" ? "modal-fullscreen" : `modal-${size}`), centered && "modal-dialog-centered", scrollable && "modal-dialog-scrollable");
|
|
5
|
+
const baseAttrs = toAttributes({
|
|
6
|
+
id,
|
|
7
|
+
tabindex: "-1",
|
|
8
|
+
"aria-hidden": "true",
|
|
9
|
+
"data-backdrop": staticBackdrop ? "static" : undefined,
|
|
10
|
+
...attributes
|
|
11
|
+
});
|
|
12
|
+
return `
|
|
13
|
+
<div class="${classNames("modal", className)}"${baseAttrs}>
|
|
14
|
+
<div class="${dialogClasses}">
|
|
15
|
+
<div class="modal-content">
|
|
16
|
+
${children}
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</div>
|
|
20
|
+
`.trim();
|
|
21
|
+
}
|
|
22
|
+
export const modal = Modal;
|
|
23
|
+
export function ModalHeader(props = {}) {
|
|
24
|
+
const { title, children = "", dismissible = true, className = "" } = props;
|
|
25
|
+
const titleHtml = title ? `<h5 class="modal-title m-0">${escapeHtml(title)}</h5>` : "";
|
|
26
|
+
const closeBtn = dismissible
|
|
27
|
+
? `<button class="modal-close btn-close" type="button" data-modal-close aria-label="Close"></button>`
|
|
28
|
+
: "";
|
|
29
|
+
return `
|
|
30
|
+
<div class="${classNames("modal-header", className)}">
|
|
31
|
+
${titleHtml}
|
|
32
|
+
${children}
|
|
33
|
+
${closeBtn}
|
|
34
|
+
</div>
|
|
35
|
+
`.trim();
|
|
36
|
+
}
|
|
37
|
+
export const modalHeader = ModalHeader;
|
|
38
|
+
export function ModalBody(props = {}) {
|
|
39
|
+
const { children = "", className = "" } = props;
|
|
40
|
+
return `<div class="${classNames("modal-body", className)}">${children}</div>`.trim();
|
|
41
|
+
}
|
|
42
|
+
export const modalBody = ModalBody;
|
|
43
|
+
export function ModalFooter(props = {}) {
|
|
44
|
+
const { children = "", className = "" } = props;
|
|
45
|
+
return `<div class="${classNames("modal-footer", className)}">${children}</div>`.trim();
|
|
46
|
+
}
|
|
47
|
+
export const modalFooter = ModalFooter;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type OffcanvasPlacement = "start" | "end" | "top" | "bottom";
|
|
2
|
+
export interface OffcanvasProps {
|
|
3
|
+
id: string;
|
|
4
|
+
children?: string;
|
|
5
|
+
placement?: OffcanvasPlacement;
|
|
6
|
+
className?: string;
|
|
7
|
+
attributes?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
export declare function Offcanvas(props: OffcanvasProps): string;
|
|
10
|
+
export declare const offcanvas: typeof Offcanvas;
|
|
11
|
+
export interface OffcanvasHeaderProps {
|
|
12
|
+
title?: string;
|
|
13
|
+
children?: string;
|
|
14
|
+
dismissible?: boolean;
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function OffcanvasHeader(props?: OffcanvasHeaderProps): string;
|
|
18
|
+
export declare const offcanvasHeader: typeof OffcanvasHeader;
|
|
19
|
+
export declare function OffcanvasBody(content?: string, className?: string): string;
|
|
20
|
+
export declare const offcanvasBody: typeof OffcanvasBody;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { classNames, escapeHtml, toAttributes } from "../utils";
|
|
2
|
+
export function Offcanvas(props) {
|
|
3
|
+
const { id, children = "", placement = "start", className = "", attributes } = props;
|
|
4
|
+
const classes = classNames("offcanvas", `offcanvas-${placement}`, className);
|
|
5
|
+
const baseAttrs = toAttributes({
|
|
6
|
+
id,
|
|
7
|
+
tabindex: "-1",
|
|
8
|
+
role: "dialog",
|
|
9
|
+
"aria-hidden": "true",
|
|
10
|
+
...attributes
|
|
11
|
+
});
|
|
12
|
+
return `<aside class="${classes}"${baseAttrs}>${children}</aside>`.trim();
|
|
13
|
+
}
|
|
14
|
+
export const offcanvas = Offcanvas;
|
|
15
|
+
export function OffcanvasHeader(props = {}) {
|
|
16
|
+
const { title, children = "", dismissible = true, className = "" } = props;
|
|
17
|
+
const titleHtml = title ? `<h5 class="offcanvas-title m-0">${escapeHtml(title)}</h5>` : "";
|
|
18
|
+
const closeBtn = dismissible
|
|
19
|
+
? `<button class="modal-close btn-close" type="button" data-offcanvas-close aria-label="Close"></button>`
|
|
20
|
+
: "";
|
|
21
|
+
return `
|
|
22
|
+
<div class="${classNames("offcanvas-header", className)}">
|
|
23
|
+
${titleHtml}
|
|
24
|
+
${children}
|
|
25
|
+
${closeBtn}
|
|
26
|
+
</div>
|
|
27
|
+
`.trim();
|
|
28
|
+
}
|
|
29
|
+
export const offcanvasHeader = OffcanvasHeader;
|
|
30
|
+
export function OffcanvasBody(content = "", className = "") {
|
|
31
|
+
return `<div class="${classNames("offcanvas-body", className)}">${content}</div>`.trim();
|
|
32
|
+
}
|
|
33
|
+
export const offcanvasBody = OffcanvasBody;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type PopoverPlacement = "top" | "bottom" | "start" | "end" | "auto";
|
|
2
|
+
export interface PopoverTriggerProps {
|
|
3
|
+
content: string;
|
|
4
|
+
placement?: PopoverPlacement;
|
|
5
|
+
title?: string;
|
|
6
|
+
children: string;
|
|
7
|
+
as?: "button" | "a" | "span" | "div";
|
|
8
|
+
className?: string;
|
|
9
|
+
attributes?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
export declare function PopoverTrigger(props: PopoverTriggerProps): string;
|
|
12
|
+
export declare const popoverTrigger: typeof PopoverTrigger;
|
|
13
|
+
export interface PopoverProps {
|
|
14
|
+
title?: string;
|
|
15
|
+
body: string;
|
|
16
|
+
className?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function Popover(props: PopoverProps): string;
|
|
19
|
+
export declare const popover: typeof Popover;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { classNames, escapeHtml, toAttributes } from "../utils";
|
|
2
|
+
export function PopoverTrigger(props) {
|
|
3
|
+
const { content, placement = "top", title, children, as: Tag = "button", className = "", attributes } = props;
|
|
4
|
+
const baseAttrs = toAttributes({
|
|
5
|
+
"data-popover": content,
|
|
6
|
+
"data-popover-placement": placement,
|
|
7
|
+
title,
|
|
8
|
+
type: Tag === "button" ? "button" : undefined,
|
|
9
|
+
...attributes
|
|
10
|
+
});
|
|
11
|
+
return `<${Tag} class="${classNames(className)}"${baseAttrs}>${children}</${Tag}>`.trim();
|
|
12
|
+
}
|
|
13
|
+
export const popoverTrigger = PopoverTrigger;
|
|
14
|
+
export function Popover(props) {
|
|
15
|
+
const { title, body, className = "" } = props;
|
|
16
|
+
const headerHtml = title ? `<div class="popover-header font-bold">${escapeHtml(title)}</div>` : "";
|
|
17
|
+
return `
|
|
18
|
+
<div class="${classNames("popover", className)}" role="tooltip">
|
|
19
|
+
${headerHtml}
|
|
20
|
+
<div class="popover-body">${body}</div>
|
|
21
|
+
</div>
|
|
22
|
+
`.trim();
|
|
23
|
+
}
|
|
24
|
+
export const popover = Popover;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type TooltipPlacement = "top" | "bottom" | "start" | "end" | "auto";
|
|
2
|
+
export interface TooltipTriggerProps {
|
|
3
|
+
title: string;
|
|
4
|
+
placement?: TooltipPlacement;
|
|
5
|
+
children: string;
|
|
6
|
+
as?: "button" | "a" | "span" | "div";
|
|
7
|
+
className?: string;
|
|
8
|
+
attributes?: Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
export declare function TooltipTrigger(props: TooltipTriggerProps): string;
|
|
11
|
+
export declare const tooltipTrigger: typeof TooltipTrigger;
|
|
12
|
+
export interface TooltipProps {
|
|
13
|
+
text: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function Tooltip(props: TooltipProps): string;
|
|
17
|
+
export declare const tooltip: typeof Tooltip;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { classNames, toAttributes } from "../utils";
|
|
2
|
+
export function TooltipTrigger(props) {
|
|
3
|
+
const { title, placement = "top", children, as: Tag = "button", className = "", attributes } = props;
|
|
4
|
+
const baseAttrs = toAttributes({
|
|
5
|
+
"data-tooltip": title,
|
|
6
|
+
"data-tooltip-placement": placement,
|
|
7
|
+
type: Tag === "button" ? "button" : undefined,
|
|
8
|
+
...attributes
|
|
9
|
+
});
|
|
10
|
+
return `<${Tag} class="${classNames(className)}"${baseAttrs}>${children}</${Tag}>`.trim();
|
|
11
|
+
}
|
|
12
|
+
export const tooltipTrigger = TooltipTrigger;
|
|
13
|
+
export function Tooltip(props) {
|
|
14
|
+
const { text, className = "" } = props;
|
|
15
|
+
return `
|
|
16
|
+
<div class="${classNames("tooltip", className)}" role="tooltip">
|
|
17
|
+
<div class="tooltip-inner">${text}</div>
|
|
18
|
+
</div>
|
|
19
|
+
`.trim();
|
|
20
|
+
}
|
|
21
|
+
export const tooltip = Tooltip;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export function escapeHtml(value) {
|
|
2
|
+
return String(value ?? "")
|
|
3
|
+
.replace(/&/g, "&")
|
|
4
|
+
.replace(/</g, "<")
|
|
5
|
+
.replace(/>/g, ">")
|
|
6
|
+
.replace(/"/g, """)
|
|
7
|
+
.replace(/'/g, "'");
|
|
8
|
+
}
|
|
9
|
+
export function classNames(...classes) {
|
|
10
|
+
return classes.filter(Boolean).join(" ").trim();
|
|
11
|
+
}
|
|
12
|
+
export function toAttributes(attributes) {
|
|
13
|
+
if (!attributes)
|
|
14
|
+
return "";
|
|
15
|
+
const parts = [];
|
|
16
|
+
for (const [key, value] of Object.entries(attributes)) {
|
|
17
|
+
if (value === true) {
|
|
18
|
+
parts.push(key);
|
|
19
|
+
}
|
|
20
|
+
else if (value !== false && value !== null && value !== undefined) {
|
|
21
|
+
parts.push(`${key}="${escapeHtml(value)}"`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return parts.length > 0 ? ` ${parts.join(" ")}` : "";
|
|
25
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@abydahana/aksara-ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"description": "Bootstrap readability with Tailwind flexibility: a static CSS and vanilla JavaScript frontend framework.",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"main": "dist/aksara.js",
|
|
10
|
+
"module": "dist/aksara.esm.js",
|
|
11
|
+
"types": "dist/aksara.d.ts",
|
|
12
|
+
"style": "dist/aksara.css",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/aksara.d.ts",
|
|
16
|
+
"import": "./dist/aksara.esm.js",
|
|
17
|
+
"require": "./dist/aksara.js",
|
|
18
|
+
"default": "./dist/aksara.esm.js"
|
|
19
|
+
},
|
|
20
|
+
"./css": "./dist/aksara.css",
|
|
21
|
+
"./css/min": "./dist/aksara.min.css",
|
|
22
|
+
"./js": {
|
|
23
|
+
"types": "./dist/aksara.d.ts",
|
|
24
|
+
"import": "./dist/aksara.esm.js",
|
|
25
|
+
"require": "./dist/aksara.js",
|
|
26
|
+
"default": "./dist/aksara.esm.js"
|
|
27
|
+
},
|
|
28
|
+
"./components": {
|
|
29
|
+
"types": "./dist/components/index.d.ts",
|
|
30
|
+
"import": "./dist/components/index.js",
|
|
31
|
+
"default": "./dist/components/index.js"
|
|
32
|
+
},
|
|
33
|
+
"./components/form": {
|
|
34
|
+
"types": "./dist/components/form/index.d.ts",
|
|
35
|
+
"import": "./dist/components/form/index.js",
|
|
36
|
+
"default": "./dist/components/form/index.js"
|
|
37
|
+
},
|
|
38
|
+
"./components/data": {
|
|
39
|
+
"types": "./dist/components/data/index.d.ts",
|
|
40
|
+
"import": "./dist/components/data/index.js",
|
|
41
|
+
"default": "./dist/components/data/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./components/feedback": {
|
|
44
|
+
"types": "./dist/components/feedback/index.d.ts",
|
|
45
|
+
"import": "./dist/components/feedback/index.js",
|
|
46
|
+
"default": "./dist/components/feedback/index.js"
|
|
47
|
+
},
|
|
48
|
+
"./components/overlay": {
|
|
49
|
+
"types": "./dist/components/overlay/index.d.ts",
|
|
50
|
+
"import": "./dist/components/overlay/index.js",
|
|
51
|
+
"default": "./dist/components/overlay/index.js"
|
|
52
|
+
},
|
|
53
|
+
"./components/navigation": {
|
|
54
|
+
"types": "./dist/components/navigation/index.d.ts",
|
|
55
|
+
"import": "./dist/components/navigation/index.js",
|
|
56
|
+
"default": "./dist/components/navigation/index.js"
|
|
57
|
+
},
|
|
58
|
+
"./components/buttons": {
|
|
59
|
+
"types": "./dist/components/buttons/index.d.ts",
|
|
60
|
+
"import": "./dist/components/buttons/index.js",
|
|
61
|
+
"default": "./dist/components/buttons/index.js"
|
|
62
|
+
},
|
|
63
|
+
"./components/*": {
|
|
64
|
+
"types": "./dist/components/*.d.ts",
|
|
65
|
+
"import": "./dist/components/*.js",
|
|
66
|
+
"default": "./dist/components/*.js"
|
|
67
|
+
},
|
|
68
|
+
"./dist/*": "./dist/*"
|
|
69
|
+
},
|
|
70
|
+
"files": [
|
|
71
|
+
"dist",
|
|
72
|
+
"README.md",
|
|
73
|
+
"LICENSE"
|
|
74
|
+
],
|
|
75
|
+
"scripts": {
|
|
76
|
+
"build": "node --import tsx src/generator/build.ts",
|
|
77
|
+
"test": "node --import tsx src/tests/run.ts",
|
|
78
|
+
"check": "tsc --noEmit",
|
|
79
|
+
"lint": "eslint src eslint.config.js",
|
|
80
|
+
"lint:fix": "eslint src eslint.config.js --fix",
|
|
81
|
+
"format": "prettier --write . && eslint src eslint.config.js --fix",
|
|
82
|
+
"format:check": "prettier --check . && eslint src eslint.config.js",
|
|
83
|
+
"prepare": "npm run build",
|
|
84
|
+
"all": "npm run format && npm run lint && npm run test && npm run build",
|
|
85
|
+
"prepublishOnly": "npm run all"
|
|
86
|
+
},
|
|
87
|
+
"keywords": [
|
|
88
|
+
"css",
|
|
89
|
+
"frontend",
|
|
90
|
+
"framework",
|
|
91
|
+
"utilities",
|
|
92
|
+
"rtl",
|
|
93
|
+
"typescript"
|
|
94
|
+
],
|
|
95
|
+
"license": "MIT",
|
|
96
|
+
"dependencies": {
|
|
97
|
+
"@mdi/font": "^7.4.47"
|
|
98
|
+
},
|
|
99
|
+
"devDependencies": {
|
|
100
|
+
"@eslint/js": "^10.0.1",
|
|
101
|
+
"@types/node": "^22.13.14",
|
|
102
|
+
"eslint": "^10.9.1",
|
|
103
|
+
"eslint-config-prettier": "^10.1.8",
|
|
104
|
+
"eslint-plugin-unicorn": "^65.0.1",
|
|
105
|
+
"prettier": "^3.9.6",
|
|
106
|
+
"tsx": "^4.19.3",
|
|
107
|
+
"typescript": "^5.9.3",
|
|
108
|
+
"typescript-eslint": "^8.68.0"
|
|
109
|
+
},
|
|
110
|
+
"author": "Aby Dahana"
|
|
111
|
+
}
|