uibee 3.3.0 → 3.3.1

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 (161) hide show
  1. package/dist/components/alert/alert.d.ts +15 -0
  2. package/dist/components/alert/alert.js +29 -0
  3. package/dist/components/badge/badge.d.ts +16 -0
  4. package/dist/components/badge/badge.js +26 -0
  5. package/dist/components/buttons/button.d.ts +25 -0
  6. package/dist/components/buttons/button.js +44 -0
  7. package/dist/components/code/code.d.ts +23 -0
  8. package/dist/components/code/code.js +39 -0
  9. package/dist/components/confirm/confirmPopup.d.ts +23 -0
  10. package/dist/components/confirm/confirmPopup.js +52 -0
  11. package/dist/components/container/accordion.d.ts +25 -0
  12. package/dist/components/container/accordion.js +41 -0
  13. package/dist/components/container/card.d.ts +13 -0
  14. package/dist/components/container/card.js +10 -0
  15. package/dist/components/container/expandableCard.d.ts +32 -0
  16. package/dist/components/container/expandableCard.js +70 -0
  17. package/dist/components/container/glassCard.d.ts +13 -0
  18. package/dist/components/container/glassCard.js +10 -0
  19. package/dist/components/container/highlight.d.ts +10 -0
  20. package/dist/components/container/highlight.js +10 -0
  21. package/dist/components/container/iconBubble.d.ts +25 -0
  22. package/dist/components/container/iconBubble.js +21 -0
  23. package/dist/components/container/leftBarPanel.d.ts +15 -0
  24. package/dist/components/container/leftBarPanel.js +10 -0
  25. package/dist/components/container/page.d.ts +15 -0
  26. package/dist/components/container/page.js +16 -0
  27. package/dist/components/container/pulseDot.d.ts +12 -0
  28. package/dist/components/container/pulseDot.js +23 -0
  29. package/dist/components/container/statCard.d.ts +18 -0
  30. package/dist/components/container/statCard.js +25 -0
  31. package/dist/components/container/tabs.d.ts +35 -0
  32. package/dist/components/container/tabs.js +36 -0
  33. package/dist/components/empty/emptyState.d.ts +19 -0
  34. package/dist/components/empty/emptyState.js +27 -0
  35. package/dist/components/footer/footer.d.ts +49 -0
  36. package/dist/components/footer/footer.js +109 -0
  37. package/dist/components/footer/loginContent.d.ts +18 -0
  38. package/dist/components/footer/loginContent.js +138 -0
  39. package/dist/components/inputs/checkbox.d.ts +20 -0
  40. package/dist/components/inputs/checkbox.js +76 -0
  41. package/dist/components/inputs/fileInput.d.ts +19 -0
  42. package/dist/components/inputs/fileInput.js +108 -0
  43. package/dist/components/inputs/input.d.ts +16 -0
  44. package/dist/components/inputs/input.js +157 -0
  45. package/dist/components/inputs/multiSelect.d.ts +37 -0
  46. package/dist/components/inputs/multiSelect.js +99 -0
  47. package/dist/components/inputs/radio.d.ts +20 -0
  48. package/dist/components/inputs/radio.js +70 -0
  49. package/dist/components/inputs/range.d.ts +14 -0
  50. package/dist/components/inputs/range.js +60 -0
  51. package/dist/components/inputs/searchInput.d.ts +11 -0
  52. package/dist/components/inputs/searchInput.js +56 -0
  53. package/dist/components/inputs/select.d.ts +42 -0
  54. package/dist/components/inputs/select.js +164 -0
  55. package/dist/components/inputs/shared/colorPickerPopup.js +293 -0
  56. package/dist/components/inputs/shared/dateTimePickerPopup.js +225 -0
  57. package/dist/components/inputs/shared/fieldWrapper.js +33 -0
  58. package/dist/components/inputs/shared/index.js +6 -0
  59. package/dist/components/inputs/shared/inputError.js +17 -0
  60. package/dist/components/inputs/shared/inputInfo.js +13 -0
  61. package/dist/components/inputs/shared/inputLabel.js +19 -0
  62. package/dist/components/inputs/switch.d.ts +14 -0
  63. package/dist/components/inputs/switch.js +37 -0
  64. package/dist/components/inputs/tagInput.d.ts +31 -0
  65. package/dist/components/inputs/tagInput.js +72 -0
  66. package/dist/components/inputs/textarea.d.ts +14 -0
  67. package/dist/components/inputs/textarea.js +76 -0
  68. package/dist/components/inputs/toggle.d.ts +21 -0
  69. package/dist/components/inputs/toggle.js +33 -0
  70. package/dist/components/login/loginPage.d.ts +15 -0
  71. package/dist/components/login/loginPage.js +80 -0
  72. package/dist/components/logo/logo.d.ts +9 -0
  73. package/dist/components/logo/logo.js +138 -0
  74. package/dist/components/logo/logoSmall.d.ts +4 -0
  75. package/dist/components/logo/logoSmall.js +56 -0
  76. package/dist/components/markdownrender/markdownRender.d.ts +16 -0
  77. package/dist/components/markdownrender/markdownRender.js +59 -0
  78. package/dist/components/modal/modal.d.ts +22 -0
  79. package/dist/components/modal/modal.js +59 -0
  80. package/dist/components/navbar/bubble.js +36 -0
  81. package/dist/components/navbar/navbar.d.ts +50 -0
  82. package/dist/components/navbar/navbar.js +99 -0
  83. package/dist/components/navbar/navbarDropdown.d.ts +15 -0
  84. package/dist/components/navbar/navbarDropdown.js +63 -0
  85. package/dist/components/navbar/navbarItem.d.ts +23 -0
  86. package/dist/components/navbar/navbarItem.js +38 -0
  87. package/dist/components/sidebar/sidebar.d.ts +34 -0
  88. package/dist/components/sidebar/sidebar.js +135 -0
  89. package/dist/components/spinner/spinner.d.ts +11 -0
  90. package/dist/components/spinner/spinner.js +16 -0
  91. package/dist/components/table/body.js +253 -0
  92. package/dist/components/table/constants.js +58 -0
  93. package/dist/components/table/empty.js +24 -0
  94. package/dist/components/table/format.js +39 -0
  95. package/dist/components/table/header.js +109 -0
  96. package/dist/components/table/menu.d.ts +18 -0
  97. package/dist/components/table/menu.js +76 -0
  98. package/dist/components/table/pagination.d.ts +14 -0
  99. package/dist/components/table/pagination.js +130 -0
  100. package/dist/components/table/skeleton.js +39 -0
  101. package/dist/components/table/table.d.ts +7 -0
  102. package/dist/components/table/table.js +213 -0
  103. package/dist/components/table/types.d.ts +52 -0
  104. package/dist/components/table/utils.js +9 -0
  105. package/dist/components/toast/toastItem.js +61 -0
  106. package/dist/components/toast/toaster.d.ts +13 -0
  107. package/dist/components/toast/toaster.js +117 -0
  108. package/dist/components/toggle/language.d.ts +10 -0
  109. package/dist/components/toggle/language.js +34 -0
  110. package/dist/components/toggle/theme.d.ts +8 -0
  111. package/dist/components/toggle/theme.js +135 -0
  112. package/dist/components/version/version.d.ts +13 -0
  113. package/dist/components/version/version.js +19 -0
  114. package/dist/components/vulnerability/constants.d.ts +4 -0
  115. package/dist/components/vulnerability/constants.js +17 -0
  116. package/dist/components/vulnerability/severityPill.d.ts +15 -0
  117. package/dist/components/vulnerability/severityPill.js +20 -0
  118. package/dist/{style.css → globals.css} +152 -226
  119. package/dist/hooks/useClickOutside.d.ts +6 -0
  120. package/dist/{useClickOutside-Cmp-RsP3.js → hooks/useClickOutside.js} +1 -1
  121. package/dist/hooks/useDarkMode.d.ts +4 -0
  122. package/dist/hooks/useDarkMode.js +19 -0
  123. package/dist/hooks/useVisibility.d.ts +7 -0
  124. package/dist/hooks/useVisibility.js +25 -0
  125. package/dist/icons/icons.d.ts +420 -0
  126. package/dist/{icons-lZYQ6Vlr.js → icons/icons.js} +1 -1
  127. package/dist/src/components/index.d.ts +51 -905
  128. package/dist/src/components/index.js +49 -4179
  129. package/dist/src/hooks/index.d.ts +3 -14
  130. package/dist/src/hooks/index.js +3 -42
  131. package/dist/src/icons/index.d.ts +1 -419
  132. package/dist/src/icons/index.js +1 -1
  133. package/dist/src/styles/index.js +1 -1
  134. package/dist/src/utils/index.d.ts +5 -37
  135. package/dist/src/utils/index.js +5 -124
  136. package/dist/utils/auth/callback.d.ts +14 -0
  137. package/dist/utils/auth/callback.js +53 -0
  138. package/dist/utils/auth/getDomain.js +6 -0
  139. package/dist/utils/auth/login.d.ts +12 -0
  140. package/dist/utils/auth/login.js +17 -0
  141. package/dist/utils/auth/logout.d.ts +10 -0
  142. package/dist/utils/auth/logout.js +20 -0
  143. package/dist/utils/auth/token.d.ts +10 -0
  144. package/dist/utils/auth/token.js +30 -0
  145. package/dist/utils/logoConsoleOutput/logoConsoleOutput.d.ts +4 -0
  146. package/dist/utils/logoConsoleOutput/logoConsoleOutput.js +11 -0
  147. package/package.json +1 -1
  148. package/src/components/buttons/button.tsx +2 -0
  149. package/src/components/footer/footer.tsx +60 -42
  150. package/src/components/index.ts +0 -1
  151. package/src/components/inputs/checkbox.tsx +2 -0
  152. package/src/components/inputs/input.tsx +2 -0
  153. package/src/components/inputs/radio.tsx +2 -0
  154. package/src/components/inputs/range.tsx +2 -0
  155. package/src/components/inputs/shared/colorPickerPopup.tsx +2 -0
  156. package/src/components/inputs/shared/dateTimePickerPopup.tsx +2 -0
  157. package/src/components/inputs/textarea.tsx +2 -0
  158. package/src/components/inputs/toggle.tsx +2 -0
  159. package/src/components/toast/toastItem.tsx +2 -0
  160. package/src/globals.css +5 -0
  161. package/tsdown.config.ts +1 -0
@@ -0,0 +1,14 @@
1
+ import { AuthCallbackProps } from "uibee/utils";
2
+
3
+ //#region src/utils/auth/callback.d.ts
4
+ declare function authCallback({
5
+ req,
6
+ tokenURL,
7
+ clientID,
8
+ clientSecret,
9
+ redirectPath,
10
+ userInfoURL,
11
+ tokenRedirectPath
12
+ }: AuthCallbackProps): Promise<Response>;
13
+ //#endregion
14
+ export { authCallback as default };
@@ -0,0 +1,53 @@
1
+ import { getDomain } from "./getDomain.js";
2
+ import { NextResponse } from "next/server.js";
3
+ //#region src/utils/auth/callback.ts
4
+ async function authCallback({ req, tokenURL, clientID, clientSecret, redirectPath, userInfoURL, tokenRedirectPath }) {
5
+ const domain = getDomain(req);
6
+ const searchParams = new URL(req.url).searchParams;
7
+ if (!searchParams) return NextResponse.json({ error: "No search parameters found." }, { status: 400 });
8
+ const code = searchParams.get("code");
9
+ if (!code) return NextResponse.json({ error: "No authorization code found." }, { status: 400 });
10
+ try {
11
+ const tokenResponse = await fetch(tokenURL, {
12
+ method: "POST",
13
+ headers: { "Content-Type": "application/x-www-form-urlencoded" },
14
+ body: new URLSearchParams({
15
+ client_id: clientID,
16
+ client_secret: clientSecret,
17
+ code,
18
+ redirect_uri: `${domain}${redirectPath}`,
19
+ grant_type: "authorization_code"
20
+ }).toString()
21
+ });
22
+ const tokenResponseBody = await tokenResponse.text();
23
+ if (!tokenResponse.ok) return new Response(JSON.stringify(`Failed to obtain token: ${tokenResponseBody}`), {
24
+ status: 500,
25
+ headers: { "Content-Type": "application/json" }
26
+ });
27
+ const token = JSON.parse(tokenResponseBody);
28
+ const userInfoResponse = await fetch(userInfoURL, { headers: { Authorization: `Bearer ${token.access_token}` } });
29
+ if (!userInfoResponse.ok) {
30
+ const userInfoError = await userInfoResponse.text();
31
+ return new Response(`No user info found: ${userInfoError}`, {
32
+ status: 500,
33
+ headers: { "Content-Type": "application/json" }
34
+ });
35
+ }
36
+ const userInfo = await userInfoResponse.json();
37
+ const redirectUrl = new URL(`${domain}${tokenRedirectPath}`);
38
+ redirectUrl.search = new URLSearchParams({
39
+ id: userInfo.sub,
40
+ name: userInfo.name,
41
+ username: userInfo.nickname,
42
+ email: userInfo.email,
43
+ groups: userInfo.groups.join(","),
44
+ access_token: token.access_token
45
+ }).toString();
46
+ return NextResponse.redirect(redirectUrl.toString());
47
+ } catch (err) {
48
+ console.error("Error during OAuth flow:", err.message);
49
+ return NextResponse.json({ error: "Authentication failed" }, { status: 500 });
50
+ }
51
+ }
52
+ //#endregion
53
+ export { authCallback as default };
@@ -0,0 +1,6 @@
1
+ //#region src/utils/auth/getDomain.ts
2
+ function getDomain(req) {
3
+ return `${req.headers.get("x-forwarded-proto") ?? new URL(req.url).protocol.replace(":", "")}://${req.headers.get("host") ?? req.headers.get("x-forwarded-host") ?? new URL(req.url).host}`;
4
+ }
5
+ //#endregion
6
+ export { getDomain };
@@ -0,0 +1,12 @@
1
+ import { NextResponse } from "next/server.js";
2
+ import { AuthLoginProps } from "uibee/utils";
3
+
4
+ //#region src/utils/auth/login.d.ts
5
+ declare function AuthLogin({
6
+ req,
7
+ clientID,
8
+ redirectPath,
9
+ authURL
10
+ }: AuthLoginProps): Promise<NextResponse<unknown>>;
11
+ //#endregion
12
+ export { AuthLogin as default };
@@ -0,0 +1,17 @@
1
+ import { getDomain } from "./getDomain.js";
2
+ import { NextResponse } from "next/server.js";
3
+ //#region src/utils/auth/login.ts
4
+ async function AuthLogin({ req, clientID, redirectPath, authURL }) {
5
+ const domain = getDomain(req);
6
+ const state = Math.random().toString(36).substring(5);
7
+ const authQueryParams = new URLSearchParams({
8
+ client_id: clientID,
9
+ redirect_uri: `${domain}${redirectPath}`,
10
+ response_type: "code",
11
+ scope: "openid profile email",
12
+ state
13
+ }).toString();
14
+ return NextResponse.redirect(`${authURL}?${authQueryParams}`);
15
+ }
16
+ //#endregion
17
+ export { AuthLogin as default };
@@ -0,0 +1,10 @@
1
+ import { NextResponse } from "next/server.js";
2
+ import { AuthLogoutProps } from "uibee/utils";
3
+
4
+ //#region src/utils/auth/logout.d.ts
5
+ declare function AuthLogout({
6
+ req,
7
+ path
8
+ }: AuthLogoutProps): Promise<NextResponse<unknown>>;
9
+ //#endregion
10
+ export { AuthLogout as default };
@@ -0,0 +1,20 @@
1
+ import { getDomain } from "./getDomain.js";
2
+ import { NextResponse } from "next/server.js";
3
+ //#region src/utils/auth/logout.ts
4
+ async function AuthLogout({ req, path }) {
5
+ const domain = getDomain(req);
6
+ const response = NextResponse.redirect(new URL(path || "/", domain));
7
+ [
8
+ "access_token",
9
+ "user_id",
10
+ "user_name",
11
+ "user_nickname",
12
+ "user_email",
13
+ "user_groups"
14
+ ].forEach((cookieName) => {
15
+ response.cookies.delete(cookieName);
16
+ });
17
+ return response;
18
+ }
19
+ //#endregion
20
+ export { AuthLogout as default };
@@ -0,0 +1,10 @@
1
+ import { NextResponse } from "next/server.js";
2
+ import { AuthTokenProps } from "uibee/utils";
3
+
4
+ //#region src/utils/auth/token.d.ts
5
+ declare function AuthToken({
6
+ req,
7
+ redirectPath
8
+ }: AuthTokenProps): Promise<NextResponse<unknown>>;
9
+ //#endregion
10
+ export { AuthToken as default };
@@ -0,0 +1,30 @@
1
+ import { getDomain } from "./getDomain.js";
2
+ import { NextResponse } from "next/server.js";
3
+ //#region src/utils/auth/token.ts
4
+ async function AuthToken({ req, redirectPath }) {
5
+ const domain = getDomain(req);
6
+ const url = new URL(req.url);
7
+ const token = url.searchParams.get("access_token");
8
+ const btg = url.searchParams.get("btg");
9
+ const redirectCookie = req.cookies.get("redirect_after_login");
10
+ const redirect = redirectCookie ? redirectCookie.value : redirectPath || "/";
11
+ if (!token) return NextResponse.json({ error: "No access token provided" }, { status: 400 });
12
+ if (btg) return NextResponse.redirect(new URL(redirect, domain));
13
+ const accessToken = url.searchParams.get("access_token");
14
+ const userID = url.searchParams.get("id");
15
+ const username = url.searchParams.get("name");
16
+ const userNickname = url.searchParams.get("username");
17
+ const userEmail = url.searchParams.get("email");
18
+ const userGroups = url.searchParams.get("groups");
19
+ const response = NextResponse.redirect(new URL(redirect, domain));
20
+ response.cookies.set("access_token", accessToken);
21
+ response.cookies.set("user_id", userID);
22
+ response.cookies.set("user_name", username);
23
+ response.cookies.set("user_nickname", userNickname);
24
+ response.cookies.set("user_email", userEmail);
25
+ response.cookies.set("user_groups", userGroups);
26
+ if (redirectCookie) response.cookies.delete("redirect_after_login");
27
+ return response;
28
+ }
29
+ //#endregion
30
+ export { AuthToken as default };
@@ -0,0 +1,4 @@
1
+ //#region src/utils/logoConsoleOutput/logoConsoleOutput.d.ts
2
+ declare function LogoConsoleOutput(): void;
3
+ //#endregion
4
+ export { LogoConsoleOutput };
@@ -0,0 +1,11 @@
1
+ //#region src/utils/logoConsoleOutput/logoConsoleOutput.ts
2
+ function LogoConsoleOutput() {
3
+ const ua = navigator.userAgent;
4
+ if (!ua.includes("Chrome") && !ua.includes("Firefox") && !ua.includes("Safari")) {
5
+ console.log("Login - Linjeforeningen for IT");
6
+ return;
7
+ }
8
+ console.log("%c███████╗ ███████╗\n██╔════╝ ╚════██║\n██║%c ██╗ ██████╗ ██████╗ ██╗███╗ ██╗ %c██║\n╚═╝%c ██║ ██╔═══██╗██╔════╝ ██║████╗ ██║ %c╚═╝%c\n ██║ ██║ ██║██║ ███╗██║██╔██╗ ██║\n ██║ ██║ ██║██║ ██║██║██║╚██╗██║\n%c██╗%c ██████╗╚██████╔╝╚██████╔╝██║██║ ╚████║ %c██╗\n██║%c ╚═════╝ ╚═════╝ ╚═════╝ ╚═╝╚═╝ ╚═══╝ %c██║\n███████╗%c %c███████║\n╚══════╝ ╚══════╝%c\n\n - Laget av TekKom med 🍕 og ❤️", "color: #fd8738", "", "color: #fd8738", "", "color: #fd8738", "", "color: #fd8738", "", "color: #fd8738", "", "color: #fd8738", "", "color: #fd8738", "");
9
+ }
10
+ //#endregion
11
+ export { LogoConsoleOutput };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uibee",
3
- "version": "3.3.0",
3
+ "version": "3.3.1",
4
4
  "description": "Shared components, functions and hooks for reuse across Login projects",
5
5
  "homepage": "https://github.com/Login-Linjeforening-for-IT/uibee#readme",
6
6
  "bugs": {
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import Link from 'next/link'
2
4
  import type { JSX } from 'react'
3
5
 
@@ -32,6 +32,41 @@ function t(s: BilingualString, lang: Lang): string {
32
32
  return typeof s === 'string' ? s : s[lang]
33
33
  }
34
34
 
35
+ function Column({ col, lang }: { col: FooterColumn; lang: Lang }) {
36
+ return (
37
+ <div>
38
+ <h4 className='pb-2 text-sm font-medium tracking-widest text-login-100'>
39
+ {t(col.heading, lang)}
40
+ </h4>
41
+ {col.items.map((item, j) =>
42
+ item.href ? (
43
+ item.href.startsWith('/') ? (
44
+ <Link
45
+ key={j}
46
+ className='link--underscore-hover block text-login-50'
47
+ href={item.href}
48
+ >
49
+ {t(item.label, lang)}
50
+ </Link>
51
+ ) : (
52
+ <a
53
+ key={j}
54
+ className='link--underscore-hover block text-login-50'
55
+ href={item.href}
56
+ >
57
+ {t(item.label, lang)}
58
+ </a>
59
+ )
60
+ ) : (
61
+ <p key={j} className='text-login-50'>
62
+ {t(item.label, lang)}
63
+ </p>
64
+ )
65
+ )}
66
+ </div>
67
+ )
68
+ }
69
+
35
70
  export default function Footer({
36
71
  logo,
37
72
  sponsor,
@@ -43,15 +78,16 @@ export default function Footer({
43
78
  className,
44
79
  }: FooterProps) {
45
80
  const year = new Date().getFullYear()
81
+ const [firstColumn, ...restColumns] = columns ?? []
46
82
  const hasRight = (columns && columns.length > 0) || (socialLinks && socialLinks.length > 0)
47
83
 
48
84
  return (
49
- <div className={`mt-24 bg-login-950 md:mt-40 ${className || ''}`}>
85
+ <div className={`max-md:mt-24 bg-login-950 md:mt-40 ${className || ''}`}>
50
86
  <div className={`
51
- mx-auto w-full px-4 pt-16 pb-24 md:max-w-304 md:px-12 md:pt-20 md:pb-4
87
+ mx-auto w-full pb-4 max-md:px-4 max-md:pt-16 md:max-w-304 md:px-12 md:pt-20
52
88
  ${hasRight ? 'md:grid md:grid-cols-[18rem_1fr] md:gap-x-12' : ''}
53
89
  `}>
54
- <div className='mx-auto grid w-full max-w-60 gap-16 md:row-span-2 md:max-w-72 md:gap-20'>
90
+ <div className='mx-auto grid w-full max-md:max-w-60 max-md:gap-16 md:row-span-2 md:max-w-72 md:gap-20'>
55
91
  <div className='block w-full'>{logo}</div>
56
92
  {sponsor && (
57
93
  <div>
@@ -65,43 +101,26 @@ export default function Footer({
65
101
  )}
66
102
  </div>
67
103
 
68
- {columns && columns.length > 0 && (
104
+ {firstColumn && (
105
+ <div className='
106
+ grid w-full self-start max-md:mt-16
107
+ max-sm:max-w-60 sm:max-md:max-w-88
108
+ md:col-start-2 md:row-start-1 md:max-w-136 md:justify-self-center
109
+ '>
110
+ <Column col={firstColumn} lang={lang} />
111
+ </div>
112
+ )}
113
+
114
+ {restColumns.length > 0 && (
69
115
  <div className={`
70
- mt-12 grid w-full max-w-60 gap-8
71
- sm:max-w-88 sm:justify-items-end sm:justify-self-end
72
- md:col-start-2 md:row-start-1 md:mt-0 md:max-w-136 md:gap-0 md:justify-self-end
73
- ${columns.length > 1 ? 'sm:grid-cols-2' : ''}
116
+ grid w-full self-start max-md:mt-16 max-md:gap-8
117
+ max-sm:max-w-60 sm:max-md:max-w-88 sm:justify-items-end sm:justify-self-end
118
+ md:col-start-2 md:row-start-1 md:max-w-136 md:justify-self-end
119
+ ${restColumns.length > 1 ? 'sm:grid-cols-2' : ''}
74
120
  `}>
75
- {columns.map((col, i) => (
121
+ {restColumns.map((col, i) => (
76
122
  <div key={i} className='sm:justify-self-center md:justify-self-end'>
77
- <h4 className='pb-2 text-sm font-medium tracking-widest text-login-100'>
78
- {t(col.heading, lang)}
79
- </h4>
80
- {col.items.map((item, j) =>
81
- item.href ? (
82
- item.href.startsWith('/') ? (
83
- <Link
84
- key={j}
85
- className='link--underscore-hover block text-login-100'
86
- href={item.href}
87
- >
88
- {t(item.label, lang)}
89
- </Link>
90
- ) : (
91
- <a
92
- key={j}
93
- className='link--underscore-hover block text-login-100'
94
- href={item.href}
95
- >
96
- {t(item.label, lang)}
97
- </a>
98
- )
99
- ) : (
100
- <p key={j} className='text-login-100'>
101
- {t(item.label, lang)}
102
- </p>
103
- )
104
- )}
123
+ <Column col={col} lang={lang} />
105
124
  </div>
106
125
  ))}
107
126
  </div>
@@ -109,11 +128,12 @@ export default function Footer({
109
128
 
110
129
  {socialLinks && socialLinks.length > 0 && (
111
130
  <div className='md:col-start-2 md:row-start-2 md:justify-self-end'>
112
- <div className='mx-auto mt-20 mb-12 flex w-fit flex-wrap justify-center gap-6'>
131
+ <div className='mx-auto mt-20 mb-12 grid w-fit gap-6 max-sm:grid-cols-3 sm:grid-flow-col'>
113
132
  {socialLinks.map((link, i) => (
114
133
  <a
115
134
  key={i}
116
- className={`block size-8 text-login-100 transition-all duration-200 group
135
+ className={`group mx-auto flex h-8 w-8 items-center justify-center
136
+ text-login-100 transition-all duration-200
117
137
  ${link.hoverClass ?? 'hover:text-login-50'}`}
118
138
  title={link.title}
119
139
  href={link.href}
@@ -127,9 +147,7 @@ export default function Footer({
127
147
  </div>
128
148
  )}
129
149
 
130
- <div className='mt-16 flex flex-col items-start gap-4 md:col-span-2 md:row-start-3 md:mt-24 md:grid
131
- md:grid-cols-[auto_min-content] md:items-end md:gap-8'
132
- >
150
+ <div className='mt-24 grid grid-cols-[auto_min-content] items-end gap-8 md:col-span-2 md:row-start-3'>
133
151
  <p className='text-xs wrap-break-word text-login-100'>
134
152
  {lang === 'no' ? 'Opphavsrett' : 'Copyright'} © {year} {t(copyright, lang)}
135
153
  </p>
@@ -1,4 +1,3 @@
1
- 'use client'
2
1
  export { default as Input } from './inputs/input'
3
2
  export { default as SearchInput } from './inputs/searchInput'
4
3
  export { default as Textarea } from './inputs/textarea'
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { Check } from 'lucide-react'
2
4
  import { FieldWrapper, InputLabel } from './shared'
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import React, { type ChangeEvent, type JSX, useRef, useState, useId } from 'react'
2
4
  import { Calendar, Clock } from 'lucide-react'
3
5
  import { FieldWrapper } from './shared'
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { FieldWrapper, InputLabel } from './shared'
2
4
 
3
5
  export type RadioOption = {
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { FieldWrapper } from './shared'
2
4
 
3
5
  export type RangeProps = Omit<React.ComponentProps<'input'>, 'name'> & {
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { type JSX, useState, useEffect, useRef } from 'react'
2
4
 
3
5
  export type ColorPickerPopupProps = {
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { useState, useEffect } from 'react'
2
4
  import { ChevronLeft, ChevronRight } from 'lucide-react'
3
5
 
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { useState } from 'react'
2
4
  import { Eye, Pencil } from 'lucide-react'
3
5
  import { FieldWrapper } from './shared'
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  type ToggleOption<T> = {
2
4
  value: T
3
5
  label?: string
@@ -1,3 +1,5 @@
1
+ 'use client'
2
+
1
3
  import { AlertCircle, AlertTriangle, CheckCircle, Info, X } from 'lucide-react'
2
4
  import { useEffect, useLayoutEffect, useRef, useState } from 'react'
3
5
  import type { ToastType, ToastProps } from 'uibee/components'
package/src/globals.css CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  @config '../tailwind.config.ts';
4
4
 
5
+ /* Apply hover styles on :hover directly instead of gating them behind
6
+ @media (hover: hover), which never matches on devices reporting hover: none. */
7
+ @custom-variant hover (&:hover);
8
+ @custom-variant group-hover (&:is(:where(.group):hover *));
9
+
5
10
  @theme {
6
11
  --breakpoint-100px: 100px;
7
12
  --breakpoint-200px: 200px;
package/tsdown.config.ts CHANGED
@@ -13,6 +13,7 @@ export default defineConfig({
13
13
  outExtensions: () => ({ js: '.js', dts: '.d.ts' }),
14
14
  dts: true,
15
15
  clean: true,
16
+ unbundle: true,
16
17
  deps: {
17
18
  onlyBundle: false,
18
19
  },