ab-nextjs-components 0.1.2 → 0.1.3

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.
Files changed (112) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +60 -14
  3. package/ab-avatar/index.tsx +90 -0
  4. package/ab-avatar/styles.module.css +62 -0
  5. package/ab-balloon/index.tsx +55 -0
  6. package/ab-balloon/styles.module.css +12 -0
  7. package/ab-brand/index.tsx +88 -0
  8. package/ab-brand/styles.module.css +54 -0
  9. package/ab-button/index.tsx +164 -0
  10. package/ab-button/styles.module.css +63 -0
  11. package/ab-collapsible/index.tsx +188 -0
  12. package/ab-collapsible/styles.module.css +98 -0
  13. package/ab-color/index.tsx +84 -0
  14. package/ab-color/styles.module.css +51 -0
  15. package/ab-demo-box/index.tsx +38 -0
  16. package/ab-demo-box/styles.module.css +13 -0
  17. package/ab-demo-code/index.tsx +62 -0
  18. package/ab-demo-code/styles.module.css +41 -0
  19. package/ab-icon/index.tsx +63 -0
  20. package/ab-icon/styles.module.css +27 -0
  21. package/ab-icon-button/index.tsx +107 -0
  22. package/ab-icon-button/styles.module.css +64 -0
  23. package/ab-image/index.tsx +83 -0
  24. package/ab-image/styles.module.css +27 -0
  25. package/ab-info/index.tsx +89 -0
  26. package/ab-info/styles.module.css +87 -0
  27. package/ab-input/index.tsx +277 -0
  28. package/ab-input/styles.module.css +101 -0
  29. package/ab-key-feature/index.tsx +60 -0
  30. package/ab-key-feature/styles.module.css +47 -0
  31. package/ab-like-button/index.tsx +116 -0
  32. package/ab-like-button/styles.module.css +60 -0
  33. package/ab-logo/index.tsx +94 -0
  34. package/ab-logo/styles.module.css +30 -0
  35. package/ab-main-headline/index.tsx +57 -0
  36. package/ab-main-headline/styles.module.css +24 -0
  37. package/ab-menu/index.tsx +119 -0
  38. package/ab-menu/styles.module.css +99 -0
  39. package/ab-name/index.tsx +49 -0
  40. package/ab-name/styles.module.css +14 -0
  41. package/ab-navbar/index.tsx +68 -0
  42. package/ab-navbar/styles.module.css +35 -0
  43. package/ab-page-paginator/index.tsx +130 -0
  44. package/ab-page-paginator/styles.module.css +47 -0
  45. package/ab-page-switcher/index.tsx +121 -0
  46. package/ab-page-switcher/styles.module.css +37 -0
  47. package/ab-preview/index.tsx +78 -0
  48. package/ab-preview/styles.module.css +26 -0
  49. package/ab-price/index.tsx +109 -0
  50. package/ab-price/styles.module.css +36 -0
  51. package/ab-price-tag/index.tsx +70 -0
  52. package/ab-price-tag/styles.module.css +81 -0
  53. package/ab-product/index.tsx +128 -0
  54. package/ab-product/styles.module.css +44 -0
  55. package/ab-product-item/index.tsx +78 -0
  56. package/ab-product-item/styles.module.css +21 -0
  57. package/ab-progress-chips/index.tsx +105 -0
  58. package/ab-progress-chips/styles.module.css +43 -0
  59. package/ab-search-result/index.tsx +79 -0
  60. package/ab-search-result/styles.module.css +48 -0
  61. package/ab-searchbar/index.tsx +150 -0
  62. package/ab-searchbar/styles.module.css +77 -0
  63. package/ab-sidebar/index.tsx +72 -0
  64. package/ab-sidebar/styles.module.css +41 -0
  65. package/ab-switch-back/index.tsx +72 -0
  66. package/ab-switch-back/styles.module.css +45 -0
  67. package/ab-tab/index.tsx +101 -0
  68. package/ab-tab/styles.module.css +65 -0
  69. package/ab-tabs/index.tsx +45 -0
  70. package/ab-tabs/styles.module.css +17 -0
  71. package/ab-test-hello/index.tsx +37 -0
  72. package/ab-test-hello/styles.module.css +25 -0
  73. package/ab-text/index.tsx +36 -0
  74. package/ab-text/styles.module.css +3 -0
  75. package/index.ts +117 -0
  76. package/package.json +152 -7
  77. package/server/ab-avatar/index.tsx +85 -0
  78. package/server/ab-avatar/styles.module.css +62 -0
  79. package/server/ab-badge/index.tsx +66 -0
  80. package/server/ab-badge/styles.module.css +39 -0
  81. package/server/ab-brand/index.tsx +87 -0
  82. package/server/ab-brand/styles.module.css +54 -0
  83. package/server/ab-button/index.tsx +144 -0
  84. package/server/ab-button/styles.module.css +63 -0
  85. package/server/ab-icon/index.tsx +61 -0
  86. package/server/ab-icon/styles.module.css +27 -0
  87. package/server/ab-key-feature/index.tsx +59 -0
  88. package/server/ab-key-feature/styles.module.css +47 -0
  89. package/server/ab-logo/index.tsx +93 -0
  90. package/server/ab-logo/styles.module.css +30 -0
  91. package/server/ab-name/index.tsx +48 -0
  92. package/server/ab-name/styles.module.css +14 -0
  93. package/server/ab-nav-link/index.tsx +60 -0
  94. package/server/ab-nav-link/styles.module.css +32 -0
  95. package/server/ab-navbar/index.tsx +64 -0
  96. package/server/ab-navbar/styles.module.css +35 -0
  97. package/server/ab-polygon/index.tsx +45 -0
  98. package/server/ab-polygon/styles.module.css +11 -0
  99. package/server/ab-sidebar/index.tsx +68 -0
  100. package/server/ab-sidebar/styles.module.css +41 -0
  101. package/server/ab-switch-back/index.tsx +71 -0
  102. package/server/ab-switch-back/styles.module.css +45 -0
  103. package/server/ab-test-hello/index.tsx +35 -0
  104. package/server/ab-test-hello/styles.module.css +22 -0
  105. package/server/ab-text/index.tsx +33 -0
  106. package/server/ab-text/styles.module.css +3 -0
  107. package/server/index.ts +27 -0
  108. package/types/index.d.ts +54 -0
  109. package/.github/ab-logo-dark.svg +0 -12
  110. package/.github/ab-logo-light.svg +0 -9
  111. package/.github/nextjs-logoname-dark.svg +0 -28
  112. package/.github/nextjs-logoname-light.svg +0 -25
@@ -0,0 +1,37 @@
1
+ /*
2
+ * @license MIT
3
+ * ~~~~~~~~~~~~
4
+ * ab-nextjs-components
5
+ * ~~~~~~~~~~~~
6
+ * Copyright (c) 2026 Abraham Ukachi. The abElements Project.
7
+ *
8
+ * @project: ab-nextjs-components
9
+ * @name: AbTestHello - Client (port of lyd-test-hello)
10
+ * @file: ab-test-hello/index.tsx
11
+ */
12
+
13
+ 'use client';
14
+
15
+ import type { ReactElement } from 'react';
16
+ import clsx from 'clsx';
17
+ import styles from './styles.module.css';
18
+
19
+ export interface AbTestHelloProps {
20
+ name: string;
21
+ src?: string;
22
+ className?: string;
23
+ }
24
+
25
+ const AbTestHello = ({ name, src, className }: AbTestHelloProps): ReactElement => {
26
+ return (
27
+ <div id="abTestHello" className={clsx('AbTestHello', styles.abTestHello, className)}>
28
+ <h2 className={styles.abTestHelloTitle}>
29
+ Hello from <span className={styles.abTestHelloName}>{name}</span>
30
+ </h2>
31
+ {src ? <span className={styles.abTestHelloSrc}>{src}</span> : null}
32
+ </div>
33
+ );
34
+ };
35
+
36
+ export default AbTestHello;
37
+ export { AbTestHello };
@@ -0,0 +1,25 @@
1
+ .abTestHello {
2
+ display: flex;
3
+ flex-direction: column;
4
+ align-items: flex-start;
5
+ text-align: left;
6
+ padding: 1.5rem;
7
+ }
8
+ .abTestHelloTitle {
9
+ margin: 0;
10
+ padding: 0.75rem 0 0.25rem;
11
+ font-size: 1rem;
12
+ }
13
+ .abTestHelloName {
14
+ font-family: ui-serif, Georgia, serif;
15
+ font-weight: 700;
16
+ color: var(--ab-primary, #6750a4);
17
+ }
18
+ .abTestHelloSrc {
19
+ font-family: ui-monospace, monospace;
20
+ font-size: 0.875rem;
21
+ opacity: 0.5;
22
+ }
23
+ .abTestHelloSrc:hover {
24
+ opacity: 0.9;
25
+ }
@@ -0,0 +1,36 @@
1
+ /*
2
+ * @license MIT
3
+ * ~~~~~~~~~~~~
4
+ * ab-nextjs-components
5
+ * ~~~~~~~~~~~~
6
+ * Copyright (c) 2026 Abraham Ukachi. The abElements Project.
7
+ *
8
+ * @project: ab-nextjs-components
9
+ * @name: AbText - Client (port of lyd-text; i18n stripped — pass value)
10
+ * @file: ab-text/index.tsx
11
+ */
12
+
13
+ 'use client';
14
+
15
+ import type { ReactElement } from 'react';
16
+ import clsx from 'clsx';
17
+ import styles from './styles.module.css';
18
+
19
+ export interface AbTextProps {
20
+ className?: string;
21
+ id?: string;
22
+ value?: string;
23
+ /** Kept for API compat; unused without i18n peer. Prefer `value`. */
24
+ origin?: string;
25
+ }
26
+
27
+ const AbText = ({ className, id, value }: AbTextProps): ReactElement => {
28
+ return (
29
+ <span id={id} className={clsx('AbText', styles.abText, className)}>
30
+ {value ?? id ?? ''}
31
+ </span>
32
+ );
33
+ };
34
+
35
+ export default AbText;
36
+ export { AbText };
@@ -0,0 +1,3 @@
1
+ .abText {
2
+ display: inline;
3
+ }
package/index.ts ADDED
@@ -0,0 +1,117 @@
1
+ /*
2
+ * @license MIT
3
+ * ~~~~~~~~~~~~
4
+ * ab-nextjs-components
5
+ * ~~~~~~~~~~~~
6
+ * Copyright (c) 2026 Abraham Ukachi. The abElements Project.
7
+ *
8
+ * @project: ab-nextjs-components
9
+ * @name: Components - Package Catalog
10
+ * @file: index.ts
11
+ */
12
+
13
+ import type { ComponentCatalogEntry } from './types'
14
+
15
+ /**
16
+ * Catalog — Phase 2–4 + Skip-override (Phase 5 components) marked Done.
17
+ * Barrel re-exports use explicit /index.tsx paths (avoid DIR_IMPORT).
18
+ */
19
+ const supportedComponents: Array<ComponentCatalogEntry> = [
20
+ // CLIENT
21
+ { name: 'AbIcon', file: 'ab-icon/index.tsx', kind: 'client', status: 'Done' },
22
+ { name: 'AbLogo', file: 'ab-logo/index.tsx', kind: 'client', status: 'Done' },
23
+ { name: 'AbButton', file: 'ab-button/index.tsx', kind: 'client', status: 'Done' },
24
+ { name: 'AbIconButton', file: 'ab-icon-button/index.tsx', kind: 'client', status: 'Done' },
25
+ { name: 'AbInput', file: 'ab-input/index.tsx', kind: 'client', status: 'Done' },
26
+ { name: 'AbBalloon', file: 'ab-balloon/index.tsx', kind: 'client', status: 'Done' },
27
+ { name: 'AbAvatar', file: 'ab-avatar/index.tsx', kind: 'client', status: 'Done' },
28
+ { name: 'AbTab', file: 'ab-tab/index.tsx', kind: 'client', status: 'Done' },
29
+ { name: 'AbTabs', file: 'ab-tabs/index.tsx', kind: 'client', status: 'Done' },
30
+ { name: 'AbMenu', file: 'ab-menu/index.tsx', kind: 'client', status: 'Done' },
31
+ { name: 'AbCollapsible', file: 'ab-collapsible/index.tsx', kind: 'client', status: 'Done' },
32
+ { name: 'AbColor', file: 'ab-color/index.tsx', kind: 'client', status: 'Done' },
33
+ { name: 'AbInfo', file: 'ab-info/index.tsx', kind: 'client', status: 'Done' },
34
+ { name: 'AbLikeButton', file: 'ab-like-button/index.tsx', kind: 'client', status: 'Done' },
35
+ { name: 'AbSearchbar', file: 'ab-searchbar/index.tsx', kind: 'client', status: 'Done' },
36
+ { name: 'AbSearchResult', file: 'ab-search-result/index.tsx', kind: 'client', status: 'Done' },
37
+ { name: 'AbPagePaginator', file: 'ab-page-paginator/index.tsx', kind: 'client', status: 'Done' },
38
+ { name: 'AbPageSwitcher', file: 'ab-page-switcher/index.tsx', kind: 'client', status: 'Done' },
39
+ { name: 'AbProgressChips', file: 'ab-progress-chips/index.tsx', kind: 'client', status: 'Done' },
40
+ { name: 'AbPrice', file: 'ab-price/index.tsx', kind: 'client', status: 'Done' },
41
+ { name: 'AbPriceTag', file: 'ab-price-tag/index.tsx', kind: 'client', status: 'Done' },
42
+ { name: 'AbImage', file: 'ab-image/index.tsx', kind: 'client', status: 'Done' },
43
+ { name: 'AbBrand', file: 'ab-brand/index.tsx', kind: 'client', status: 'Done' },
44
+ { name: 'AbName', file: 'ab-name/index.tsx', kind: 'client', status: 'Done' },
45
+ { name: 'AbNavbar', file: 'ab-navbar/index.tsx', kind: 'client', status: 'Done' },
46
+ { name: 'AbSidebar', file: 'ab-sidebar/index.tsx', kind: 'client', status: 'Done' },
47
+ { name: 'AbText', file: 'ab-text/index.tsx', kind: 'client', status: 'Done' },
48
+ { name: 'AbTestHello', file: 'ab-test-hello/index.tsx', kind: 'client', status: 'Done' },
49
+ { name: 'AbKeyFeature', file: 'ab-key-feature/index.tsx', kind: 'client', status: 'Done' },
50
+ { name: 'AbMainHeadline', file: 'ab-main-headline/index.tsx', kind: 'client', status: 'Done' },
51
+ { name: 'AbPreview', file: 'ab-preview/index.tsx', kind: 'client', status: 'Done' },
52
+ { name: 'AbProduct', file: 'ab-product/index.tsx', kind: 'client', status: 'Done' },
53
+ { name: 'AbProductItem', file: 'ab-product-item/index.tsx', kind: 'client', status: 'Done' },
54
+ { name: 'AbSwitchBack', file: 'ab-switch-back/index.tsx', kind: 'client', status: 'Done' },
55
+ { name: 'AbDemoBox', file: 'ab-demo-box/index.tsx', kind: 'client', status: 'Done' },
56
+ { name: 'AbDemoCode', file: 'ab-demo-code/index.tsx', kind: 'client', status: 'Done' },
57
+
58
+ // SERVER
59
+ { name: 'AbIcon', file: 'server/ab-icon/index.tsx', kind: 'server', status: 'Done' },
60
+ { name: 'AbLogo', file: 'server/ab-logo/index.tsx', kind: 'server', status: 'Done' },
61
+ { name: 'AbButton', file: 'server/ab-button/index.tsx', kind: 'server', status: 'Done' },
62
+ { name: 'AbAvatar', file: 'server/ab-avatar/index.tsx', kind: 'server', status: 'Done' },
63
+ { name: 'AbBadge', file: 'server/ab-badge/index.tsx', kind: 'server', status: 'Done' },
64
+ { name: 'AbPolygon', file: 'server/ab-polygon/index.tsx', kind: 'server', status: 'Done' },
65
+ { name: 'AbBrand', file: 'server/ab-brand/index.tsx', kind: 'server', status: 'Done' },
66
+ { name: 'AbName', file: 'server/ab-name/index.tsx', kind: 'server', status: 'Done' },
67
+ { name: 'AbNavbar', file: 'server/ab-navbar/index.tsx', kind: 'server', status: 'Done' },
68
+ { name: 'AbSidebar', file: 'server/ab-sidebar/index.tsx', kind: 'server', status: 'Done' },
69
+ { name: 'AbNavLink', file: 'server/ab-nav-link/index.tsx', kind: 'server', status: 'Done' },
70
+ { name: 'AbText', file: 'server/ab-text/index.tsx', kind: 'server', status: 'Done' },
71
+ { name: 'AbTestHello', file: 'server/ab-test-hello/index.tsx', kind: 'server', status: 'Done' },
72
+ { name: 'AbKeyFeature', file: 'server/ab-key-feature/index.tsx', kind: 'server', status: 'Done' },
73
+ { name: 'AbSwitchBack', file: 'server/ab-switch-back/index.tsx', kind: 'server', status: 'Done' },
74
+ ]
75
+
76
+ const abComponents = { supportedComponents }
77
+
78
+ export { supportedComponents }
79
+ export default abComponents
80
+
81
+ export { default as AbIcon } from './ab-icon/index.tsx'
82
+ export { default as AbLogo } from './ab-logo/index.tsx'
83
+ export { default as AbButton } from './ab-button/index.tsx'
84
+ export { default as AbIconButton } from './ab-icon-button/index.tsx'
85
+ export { default as AbInput } from './ab-input/index.tsx'
86
+ export { default as AbBalloon } from './ab-balloon/index.tsx'
87
+ export { default as AbAvatar } from './ab-avatar/index.tsx'
88
+ export { default as AbTab } from './ab-tab/index.tsx'
89
+ export { default as AbTabs } from './ab-tabs/index.tsx'
90
+ export { default as AbMenu } from './ab-menu/index.tsx'
91
+ export { default as AbCollapsible } from './ab-collapsible/index.tsx'
92
+ export { default as AbColor } from './ab-color/index.tsx'
93
+ export { default as AbInfo } from './ab-info/index.tsx'
94
+ export { default as AbLikeButton } from './ab-like-button/index.tsx'
95
+ export { default as AbSearchbar } from './ab-searchbar/index.tsx'
96
+ export { default as AbSearchResult } from './ab-search-result/index.tsx'
97
+ export { default as AbPagePaginator } from './ab-page-paginator/index.tsx'
98
+ export { default as AbPageSwitcher } from './ab-page-switcher/index.tsx'
99
+ export { default as AbProgressChips } from './ab-progress-chips/index.tsx'
100
+ export { default as AbPrice } from './ab-price/index.tsx'
101
+ export { default as AbPriceTag } from './ab-price-tag/index.tsx'
102
+ export { default as AbImage } from './ab-image/index.tsx'
103
+ export { default as AbBrand } from './ab-brand/index.tsx'
104
+ export { default as AbName } from './ab-name/index.tsx'
105
+ export { default as AbNavbar } from './ab-navbar/index.tsx'
106
+ export { default as AbSidebar } from './ab-sidebar/index.tsx'
107
+ export { default as AbText } from './ab-text/index.tsx'
108
+ export { default as AbTestHello } from './ab-test-hello/index.tsx'
109
+ export { default as AbKeyFeature } from './ab-key-feature/index.tsx'
110
+ export { default as AbMainHeadline } from './ab-main-headline/index.tsx'
111
+ export { default as AbPreview } from './ab-preview/index.tsx'
112
+ export { default as AbProduct } from './ab-product/index.tsx'
113
+ export { default as AbProductItem } from './ab-product-item/index.tsx'
114
+ export { default as AbSwitchBack } from './ab-switch-back/index.tsx'
115
+ export { default as AbDemoBox } from './ab-demo-box/index.tsx'
116
+ export { default as AbDemoCode } from './ab-demo-code/index.tsx'
117
+ export { default as AbPolygon } from './server/ab-polygon/index.tsx'
package/package.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "name": "ab-nextjs-components",
3
- "version": "0.1.2",
4
- "description": "🚀 A lightweight collection of server & client React components created by Abraham Ukachi, and optimized for Next.js applications 😎.",
5
- "main": "index.js",
3
+ "version": "0.1.3",
4
+ "description": "\ud83d\ude80 A lightweight collection of server & client React components created by Abraham Ukachi, and optimized for Next.js applications \ud83d\ude0e.",
5
+ "type": "module",
6
+ "main": "index.ts",
6
7
  "types": "types/index.d.ts",
7
8
  "homepage": "https://github.com/abraham-ukachi/ab-nextjs-components#readme",
8
9
  "repository": {
@@ -12,6 +13,10 @@
12
13
  "bugs": {
13
14
  "url": "https://github.com/abraham-ukachi/ab-nextjs-components/issues"
14
15
  },
16
+ "scripts": {
17
+ "lint": "eslint . --fix",
18
+ "test": "vitest run"
19
+ },
15
20
  "keywords": [
16
21
  "react",
17
22
  "nextjs",
@@ -20,7 +25,8 @@
20
25
  "components",
21
26
  "abraham",
22
27
  "ukachi",
23
- "ab-nextjs-components"
28
+ "ab-nextjs-components",
29
+ "ab-elements"
24
30
  ],
25
31
  "author": {
26
32
  "name": "Abraham Ukachi",
@@ -28,7 +34,146 @@
28
34
  "email": "abraham.ukachi@laplateforme.io"
29
35
  },
30
36
  "license": "MIT",
31
- "scripts": {
32
- "test": "echo \"Error: no test specified\" && exit 1"
37
+ "peerDependencies": {
38
+ "clsx": "^2",
39
+ "next": "16.3.4",
40
+ "react": "^19",
41
+ "react-dom": "^19",
42
+ "ab-nextjs-theme": "*",
43
+ "ab-nextjs-icons": "*",
44
+ "ab-nextjs-hooks": "*",
45
+ "ab-nextjs-animations": "*"
46
+ },
47
+ "devDependencies": {
48
+ "@types/node": "^20",
49
+ "@types/react": "^19",
50
+ "eslint": "^9.39.0",
51
+ "eslint-config-next": "16.3.4",
52
+ "next": "16.3.4",
53
+ "react": "^19",
54
+ "react-dom": "^19",
55
+ "typescript": "^5",
56
+ "vitest": "^3",
57
+ "clsx": "^2.1.1",
58
+ "ab-nextjs-hooks": "file:../ab-nextjs-hooks"
59
+ },
60
+ "files": [
61
+ "index.ts",
62
+ "types",
63
+ "server",
64
+ "ab-logo",
65
+ "ab-icon",
66
+ "ab-button",
67
+ "ab-icon-button",
68
+ "ab-input",
69
+ "README.md",
70
+ "LICENSE",
71
+ "CHANGELOG.md",
72
+ "ab-balloon",
73
+ "ab-avatar",
74
+ "ab-tab",
75
+ "ab-tabs",
76
+ "ab-menu",
77
+ "ab-collapsible",
78
+ "ab-color",
79
+ "ab-info",
80
+ "ab-like-button",
81
+ "ab-searchbar",
82
+ "ab-search-result",
83
+ "ab-page-paginator",
84
+ "ab-page-switcher",
85
+ "ab-progress-chips",
86
+ "ab-price",
87
+ "ab-price-tag",
88
+ "ab-image",
89
+ "ab-brand",
90
+ "ab-name",
91
+ "ab-navbar",
92
+ "ab-sidebar",
93
+ "ab-text",
94
+ "ab-test-hello",
95
+ "ab-key-feature",
96
+ "ab-main-headline",
97
+ "ab-preview",
98
+ "ab-product",
99
+ "ab-product-item",
100
+ "ab-switch-back",
101
+ "ab-demo-box",
102
+ "ab-demo-code"
103
+ ],
104
+ "exports": {
105
+ ".": {
106
+ "types": "./types/index.d.ts",
107
+ "default": "./index.ts"
108
+ },
109
+ "./package.json": "./package.json",
110
+ "./ab-icon": "./ab-icon/index.tsx",
111
+ "./ab-logo": "./ab-logo/index.tsx",
112
+ "./ab-button": "./ab-button/index.tsx",
113
+ "./ab-icon-button": "./ab-icon-button/index.tsx",
114
+ "./ab-input": "./ab-input/index.tsx",
115
+ "./server/ab-icon": "./server/ab-icon/index.tsx",
116
+ "./server/ab-logo": "./server/ab-logo/index.tsx",
117
+ "./server/ab-button": "./server/ab-button/index.tsx",
118
+ "./ab-balloon": "./ab-balloon/index.tsx",
119
+ "./ab-avatar": "./ab-avatar/index.tsx",
120
+ "./ab-tab": "./ab-tab/index.tsx",
121
+ "./ab-tabs": "./ab-tabs/index.tsx",
122
+ "./ab-menu": "./ab-menu/index.tsx",
123
+ "./ab-collapsible": "./ab-collapsible/index.tsx",
124
+ "./ab-color": "./ab-color/index.tsx",
125
+ "./ab-info": "./ab-info/index.tsx",
126
+ "./ab-like-button": "./ab-like-button/index.tsx",
127
+ "./server/ab-avatar": "./server/ab-avatar/index.tsx",
128
+ "./server/ab-badge": "./server/ab-badge/index.tsx",
129
+ "./ab-searchbar": "./ab-searchbar/index.tsx",
130
+ "./ab-search-result": "./ab-search-result/index.tsx",
131
+ "./ab-page-paginator": "./ab-page-paginator/index.tsx",
132
+ "./ab-page-switcher": "./ab-page-switcher/index.tsx",
133
+ "./ab-progress-chips": "./ab-progress-chips/index.tsx",
134
+ "./ab-price": "./ab-price/index.tsx",
135
+ "./ab-price-tag": "./ab-price-tag/index.tsx",
136
+ "./ab-image": "./ab-image/index.tsx",
137
+ "./server/ab-polygon": "./server/ab-polygon/index.tsx",
138
+ "./server": {
139
+ "default": "./server/index.ts"
140
+ },
141
+ "./ab-brand": "./ab-brand/index.tsx",
142
+ "./ab-name": "./ab-name/index.tsx",
143
+ "./ab-navbar": "./ab-navbar/index.tsx",
144
+ "./ab-sidebar": "./ab-sidebar/index.tsx",
145
+ "./ab-text": "./ab-text/index.tsx",
146
+ "./ab-test-hello": "./ab-test-hello/index.tsx",
147
+ "./ab-key-feature": "./ab-key-feature/index.tsx",
148
+ "./ab-main-headline": "./ab-main-headline/index.tsx",
149
+ "./ab-preview": "./ab-preview/index.tsx",
150
+ "./ab-product": "./ab-product/index.tsx",
151
+ "./ab-product-item": "./ab-product-item/index.tsx",
152
+ "./ab-switch-back": "./ab-switch-back/index.tsx",
153
+ "./ab-demo-box": "./ab-demo-box/index.tsx",
154
+ "./ab-demo-code": "./ab-demo-code/index.tsx",
155
+ "./server/ab-brand": "./server/ab-brand/index.tsx",
156
+ "./server/ab-name": "./server/ab-name/index.tsx",
157
+ "./server/ab-navbar": "./server/ab-navbar/index.tsx",
158
+ "./server/ab-sidebar": "./server/ab-sidebar/index.tsx",
159
+ "./server/ab-nav-link": "./server/ab-nav-link/index.tsx",
160
+ "./server/ab-text": "./server/ab-text/index.tsx",
161
+ "./server/ab-test-hello": "./server/ab-test-hello/index.tsx",
162
+ "./server/ab-key-feature": "./server/ab-key-feature/index.tsx",
163
+ "./server/ab-switch-back": "./server/ab-switch-back/index.tsx"
164
+ },
165
+ "peerDependenciesMeta": {
166
+ "ab-nextjs-theme": {
167
+ "optional": true
168
+ },
169
+ "ab-nextjs-icons": {
170
+ "optional": true
171
+ },
172
+ "ab-nextjs-hooks": {
173
+ "optional": true
174
+ },
175
+ "ab-nextjs-animations": {
176
+ "optional": true
177
+ }
33
178
  }
34
- }
179
+ }
@@ -0,0 +1,85 @@
1
+ /*
2
+ * @license MIT
3
+ * ~~~~~~~~~~~~
4
+ * ab-nextjs-components
5
+ * ~~~~~~~~~~~~
6
+ * Copyright (c) 2026 Abraham Ukachi. The abElements Project.
7
+ *
8
+ * @project: ab-nextjs-components
9
+ * @name: AbAvatar - Server (port of server/lyd-avatar)
10
+ * @file: server/ab-avatar/index.tsx
11
+ */
12
+
13
+ import type { ReactElement } from 'react';
14
+ import Image from 'next/image';
15
+ import Link from 'next/link';
16
+ import clsx from 'clsx';
17
+ import styles from './styles.module.css';
18
+
19
+ export interface AbAvatarProps {
20
+ isConnected: boolean;
21
+ isOnline: boolean;
22
+ icon?: 'person' | 'group';
23
+ version?: number;
24
+ image?: string;
25
+ label?: string;
26
+ className?: string;
27
+ width?: number;
28
+ height?: number;
29
+ href?: string;
30
+ offlineHref?: string;
31
+ isActive?: boolean;
32
+ noIndicator?: boolean;
33
+ }
34
+
35
+ const AbAvatar = ({
36
+ isConnected,
37
+ isOnline,
38
+ icon = 'person',
39
+ version = 1,
40
+ image,
41
+ label = 'Avatar',
42
+ className,
43
+ width = 48,
44
+ height = 48,
45
+ href = '/',
46
+ offlineHref = '/',
47
+ isActive = false,
48
+ noIndicator = false,
49
+ }: AbAvatarProps): ReactElement => {
50
+ const src = image ?? `/assets/images/avatars/avatar_${version}.png`;
51
+
52
+ return (
53
+ <div className={clsx('AbAvatar', styles.abAvatar, className)}>
54
+ {isConnected ? (
55
+ <Link href={href} className={clsx(styles.abAvatarLink, isActive && styles.isActive)}>
56
+ <span className={styles.abAvatarImageWrap}>
57
+ <Image
58
+ src={src}
59
+ className={styles.abAvatarImage}
60
+ width={width}
61
+ height={height}
62
+ alt={label}
63
+ />
64
+ {!noIndicator ? (
65
+ <span
66
+ className={clsx(styles.abAvatarIndicator, !isOnline && styles.isOffline)}
67
+ aria-hidden
68
+ />
69
+ ) : null}
70
+ </span>
71
+ </Link>
72
+ ) : (
73
+ <Link href={offlineHref} className={styles.abAvatarOffline}>
74
+ <span className={clsx('material-symbols-rounded', styles.abAvatarIcon)} aria-hidden>
75
+ {icon}
76
+ </span>
77
+ {label ? <span className={styles.abAvatarLabel}>{label}</span> : null}
78
+ </Link>
79
+ )}
80
+ </div>
81
+ );
82
+ };
83
+
84
+ export default AbAvatar;
85
+ export { AbAvatar };
@@ -0,0 +1,62 @@
1
+ /* AbAvatar — plain CSS (no Tailwind apply) */
2
+ .abAvatar {
3
+ display: flex;
4
+ flex-direction: column;
5
+ width: auto;
6
+ height: auto;
7
+ pointer-events: auto;
8
+ }
9
+
10
+ .abAvatarLink {
11
+ position: relative;
12
+ display: inline-flex;
13
+ text-decoration: none;
14
+ opacity: 1;
15
+ }
16
+
17
+ .isActive {
18
+ opacity: 0.9;
19
+ }
20
+
21
+ .abAvatarImageWrap {
22
+ position: relative;
23
+ display: inline-flex;
24
+ }
25
+
26
+ .abAvatarImage {
27
+ border-radius: 9999px;
28
+ object-fit: cover;
29
+ }
30
+
31
+ .abAvatarIndicator {
32
+ position: absolute;
33
+ right: 0;
34
+ bottom: 0;
35
+ width: 1rem;
36
+ height: 1rem;
37
+ border-radius: 9999px;
38
+ border: 2px solid var(--ab-surface, #fff);
39
+ background: #22c55e;
40
+ }
41
+
42
+ .abAvatarIndicator.isOffline {
43
+ background: #ef4444;
44
+ }
45
+
46
+ .abAvatarOffline {
47
+ display: inline-flex;
48
+ flex-direction: column;
49
+ align-items: center;
50
+ gap: 0.25rem;
51
+ text-decoration: none;
52
+ color: inherit;
53
+ }
54
+
55
+ .abAvatarIcon {
56
+ font-size: 1.75rem;
57
+ line-height: 1;
58
+ }
59
+
60
+ .abAvatarLabel {
61
+ font-size: 0.75rem;
62
+ }
@@ -0,0 +1,66 @@
1
+ /*
2
+ * @license MIT
3
+ * ~~~~~~~~~~~~
4
+ * ab-nextjs-components
5
+ * ~~~~~~~~~~~~
6
+ * Copyright (c) 2026 Abraham Ukachi. The abElements Project.
7
+ *
8
+ * @project: ab-nextjs-components
9
+ * @name: AbBadge - Server (port of server/lyd-badge)
10
+ * @file: server/ab-badge/index.tsx
11
+ */
12
+
13
+ import type { CSSProperties, ReactElement } from 'react';
14
+ import clsx from 'clsx';
15
+ import styles from './styles.module.css';
16
+
17
+ export interface AbBadgeProps {
18
+ className?: string;
19
+ hidden?: boolean;
20
+ style?: CSSProperties;
21
+ color?: 'default' | 'red';
22
+ count: number;
23
+ position?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
24
+ size?: 'small' | 'medium' | 'large';
25
+ maxCount?: number;
26
+ }
27
+
28
+ function formatCount(count: number, maxCount: number): string {
29
+ return count > maxCount ? `${maxCount}+` : String(count);
30
+ }
31
+
32
+ /** Server AbBadge — count pill. No 'use client'. */
33
+ const AbBadge = ({
34
+ className,
35
+ hidden = false,
36
+ style,
37
+ color = 'default',
38
+ count,
39
+ position = 'top-right',
40
+ size = 'small',
41
+ maxCount = 99,
42
+ }: AbBadgeProps): ReactElement | null => {
43
+ if (hidden) return null;
44
+
45
+ return (
46
+ <span
47
+ className={clsx(
48
+ 'AbBadge',
49
+ styles.abBadge,
50
+ styles[`color_${color}`],
51
+ styles[`pos_${position.replace('-', '_')}`],
52
+ styles[`size_${size}`],
53
+ className,
54
+ )}
55
+ style={style}
56
+ data-color={color}
57
+ data-position={position}
58
+ data-size={size}
59
+ >
60
+ <span className={styles.abBadgeValue}>{formatCount(count, maxCount)}</span>
61
+ </span>
62
+ );
63
+ };
64
+
65
+ export default AbBadge;
66
+ export { AbBadge };
@@ -0,0 +1,39 @@
1
+ /* AbBadge — server, plain CSS */
2
+ .abBadge {
3
+ position: absolute;
4
+ display: inline-flex;
5
+ width: fit-content;
6
+ height: fit-content;
7
+ overflow: hidden;
8
+ border-radius: 9999px;
9
+ padding: 0.125rem 0.375rem;
10
+ font-weight: 700;
11
+ line-height: 1.25;
12
+ pointer-events: none;
13
+ }
14
+
15
+ .abBadgeValue {
16
+ overflow: hidden;
17
+ text-overflow: ellipsis;
18
+ white-space: nowrap;
19
+ letter-spacing: 0.04em;
20
+ }
21
+
22
+ .color_default {
23
+ background: var(--ab-badge-bg, #e8def8);
24
+ color: var(--ab-badge-fg, #4a4458);
25
+ }
26
+
27
+ .color_red {
28
+ background: #dc2626;
29
+ color: #fff;
30
+ }
31
+
32
+ .pos_top_left { top: 0.25rem; left: 0.375rem; }
33
+ .pos_top_right { top: 0.25rem; right: 0.375rem; }
34
+ .pos_bottom_left { bottom: 0.25rem; left: 0.375rem; }
35
+ .pos_bottom_right { bottom: 0.25rem; right: 0.375rem; }
36
+
37
+ .size_small { font-size: 0.75rem; }
38
+ .size_medium { font-size: 0.875rem; }
39
+ .size_large { font-size: 1rem; }