analytica-frontend-lib 1.1.1 → 1.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.
- package/dist/Auth/useUrlAuthentication/index.d.mts +8 -3
- package/dist/Auth/useUrlAuthentication/index.d.ts +8 -3
- package/dist/Auth/useUrlAuthentication/index.js +21 -0
- package/dist/Auth/useUrlAuthentication/index.js.map +1 -1
- package/dist/Auth/useUrlAuthentication/index.mjs +21 -0
- package/dist/Auth/useUrlAuthentication/index.mjs.map +1 -1
- package/dist/MultipleChoice/index.js.map +1 -1
- package/dist/MultipleChoice/index.mjs.map +1 -1
- package/dist/Quiz/index.js +37 -30
- package/dist/Quiz/index.js.map +1 -1
- package/dist/Quiz/index.mjs +37 -30
- package/dist/Quiz/index.mjs.map +1 -1
- package/dist/Quiz/useQuizStore/index.d.mts +1 -0
- package/dist/Quiz/useQuizStore/index.d.ts +1 -0
- package/dist/Quiz/useQuizStore/index.js +9 -0
- package/dist/Quiz/useQuizStore/index.js.map +1 -1
- package/dist/Quiz/useQuizStore/index.mjs +9 -0
- package/dist/Quiz/useQuizStore/index.mjs.map +1 -1
- package/dist/index.js +58 -30
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +58 -30
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -4,21 +4,24 @@
|
|
|
4
4
|
* @template Tokens - Type for authentication tokens
|
|
5
5
|
* @template Session - Type for session information
|
|
6
6
|
* @template Profile - Type for profile information
|
|
7
|
+
* @template User - Type for user information
|
|
7
8
|
*
|
|
8
9
|
* @interface UseUrlAuthOptions
|
|
9
10
|
* @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens
|
|
10
11
|
* @property {(session: Session) => void} setSessionInfo - Function to set session information
|
|
11
12
|
* @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile
|
|
13
|
+
* @property {(user: User) => void} [setUser] - Optional function to set user data
|
|
12
14
|
* @property {object} api - API instance with get method
|
|
13
15
|
* @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method
|
|
14
16
|
* @property {string} endpoint - API endpoint to fetch session data
|
|
15
17
|
* @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function
|
|
16
18
|
* @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing
|
|
17
19
|
*/
|
|
18
|
-
interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown> {
|
|
20
|
+
interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown> {
|
|
19
21
|
setTokens: (tokens: Tokens) => void;
|
|
20
22
|
setSessionInfo: (session: Session) => void;
|
|
21
23
|
setSelectedProfile?: (profile: Profile) => void;
|
|
24
|
+
setUser?: (user: User) => void;
|
|
22
25
|
api: {
|
|
23
26
|
get: (endpoint: string, config: unknown) => Promise<unknown>;
|
|
24
27
|
};
|
|
@@ -37,8 +40,9 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
|
|
|
37
40
|
* @template Tokens - Type for authentication tokens
|
|
38
41
|
* @template Session - Type for session information
|
|
39
42
|
* @template Profile - Type for profile information
|
|
43
|
+
* @template User - Type for user information
|
|
40
44
|
*
|
|
41
|
-
* @param {UseUrlAuthOptions<Tokens, Session, Profile>} options - Configuration options
|
|
45
|
+
* @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options
|
|
42
46
|
* @returns {void}
|
|
43
47
|
*
|
|
44
48
|
* @example
|
|
@@ -47,12 +51,13 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
|
|
|
47
51
|
* setTokens: (tokens) => authStore.setTokens(tokens),
|
|
48
52
|
* setSessionInfo: (session) => authStore.setSessionInfo(session),
|
|
49
53
|
* setSelectedProfile: (profile) => authStore.setProfile(profile),
|
|
54
|
+
* setUser: (user) => authStore.setUser(user),
|
|
50
55
|
* api: apiInstance,
|
|
51
56
|
* endpoint: '/auth/session',
|
|
52
57
|
* clearParamsFromURL: () => navigate('/', { replace: true })
|
|
53
58
|
* });
|
|
54
59
|
* ```
|
|
55
60
|
*/
|
|
56
|
-
declare function useUrlAuthentication<Tokens = unknown, Session = unknown, Profile = unknown>(options: UseUrlAuthOptions<Tokens, Session, Profile>): void;
|
|
61
|
+
declare function useUrlAuthentication<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>): void;
|
|
57
62
|
|
|
58
63
|
export { type UseUrlAuthOptions, useUrlAuthentication };
|
|
@@ -4,21 +4,24 @@
|
|
|
4
4
|
* @template Tokens - Type for authentication tokens
|
|
5
5
|
* @template Session - Type for session information
|
|
6
6
|
* @template Profile - Type for profile information
|
|
7
|
+
* @template User - Type for user information
|
|
7
8
|
*
|
|
8
9
|
* @interface UseUrlAuthOptions
|
|
9
10
|
* @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens
|
|
10
11
|
* @property {(session: Session) => void} setSessionInfo - Function to set session information
|
|
11
12
|
* @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile
|
|
13
|
+
* @property {(user: User) => void} [setUser] - Optional function to set user data
|
|
12
14
|
* @property {object} api - API instance with get method
|
|
13
15
|
* @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method
|
|
14
16
|
* @property {string} endpoint - API endpoint to fetch session data
|
|
15
17
|
* @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function
|
|
16
18
|
* @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing
|
|
17
19
|
*/
|
|
18
|
-
interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown> {
|
|
20
|
+
interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown> {
|
|
19
21
|
setTokens: (tokens: Tokens) => void;
|
|
20
22
|
setSessionInfo: (session: Session) => void;
|
|
21
23
|
setSelectedProfile?: (profile: Profile) => void;
|
|
24
|
+
setUser?: (user: User) => void;
|
|
22
25
|
api: {
|
|
23
26
|
get: (endpoint: string, config: unknown) => Promise<unknown>;
|
|
24
27
|
};
|
|
@@ -37,8 +40,9 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
|
|
|
37
40
|
* @template Tokens - Type for authentication tokens
|
|
38
41
|
* @template Session - Type for session information
|
|
39
42
|
* @template Profile - Type for profile information
|
|
43
|
+
* @template User - Type for user information
|
|
40
44
|
*
|
|
41
|
-
* @param {UseUrlAuthOptions<Tokens, Session, Profile>} options - Configuration options
|
|
45
|
+
* @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options
|
|
42
46
|
* @returns {void}
|
|
43
47
|
*
|
|
44
48
|
* @example
|
|
@@ -47,12 +51,13 @@ interface UseUrlAuthOptions<Tokens = unknown, Session = unknown, Profile = unkno
|
|
|
47
51
|
* setTokens: (tokens) => authStore.setTokens(tokens),
|
|
48
52
|
* setSessionInfo: (session) => authStore.setSessionInfo(session),
|
|
49
53
|
* setSelectedProfile: (profile) => authStore.setProfile(profile),
|
|
54
|
+
* setUser: (user) => authStore.setUser(user),
|
|
50
55
|
* api: apiInstance,
|
|
51
56
|
* endpoint: '/auth/session',
|
|
52
57
|
* clearParamsFromURL: () => navigate('/', { replace: true })
|
|
53
58
|
* });
|
|
54
59
|
* ```
|
|
55
60
|
*/
|
|
56
|
-
declare function useUrlAuthentication<Tokens = unknown, Session = unknown, Profile = unknown>(options: UseUrlAuthOptions<Tokens, Session, Profile>): void;
|
|
61
|
+
declare function useUrlAuthentication<Tokens = unknown, Session = unknown, Profile = unknown, User = unknown>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>): void;
|
|
57
62
|
|
|
58
63
|
export { type UseUrlAuthOptions, useUrlAuthentication };
|
|
@@ -50,6 +50,25 @@ var handleProfileSelection = (responseData, setSelectedProfile) => {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
};
|
|
53
|
+
var handleUserData = (responseData, setUser) => {
|
|
54
|
+
if (!setUser) return;
|
|
55
|
+
if (!hasValidProfileData(responseData)) return;
|
|
56
|
+
const userId = responseData.userId;
|
|
57
|
+
const userName = responseData.userName;
|
|
58
|
+
const userEmail = responseData.userEmail;
|
|
59
|
+
if (userId) {
|
|
60
|
+
const userData = {
|
|
61
|
+
id: userId
|
|
62
|
+
};
|
|
63
|
+
if (userName) {
|
|
64
|
+
userData.name = userName;
|
|
65
|
+
}
|
|
66
|
+
if (userEmail) {
|
|
67
|
+
userData.email = userEmail;
|
|
68
|
+
}
|
|
69
|
+
setUser(userData);
|
|
70
|
+
}
|
|
71
|
+
};
|
|
53
72
|
function useUrlAuthentication(options) {
|
|
54
73
|
const location = (0, import_react_router_dom.useLocation)();
|
|
55
74
|
(0, import_react.useEffect)(() => {
|
|
@@ -70,6 +89,7 @@ function useUrlAuthentication(options) {
|
|
|
70
89
|
});
|
|
71
90
|
options.setSessionInfo(response.data.data);
|
|
72
91
|
handleProfileSelection(response.data.data, options.setSelectedProfile);
|
|
92
|
+
handleUserData(response.data.data, options.setUser);
|
|
73
93
|
options.clearParamsFromURL?.();
|
|
74
94
|
} catch (error) {
|
|
75
95
|
console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
|
|
@@ -80,6 +100,7 @@ function useUrlAuthentication(options) {
|
|
|
80
100
|
location.search,
|
|
81
101
|
options.setSessionInfo,
|
|
82
102
|
options.setSelectedProfile,
|
|
103
|
+
options.setUser,
|
|
83
104
|
options.setTokens,
|
|
84
105
|
options.api,
|
|
85
106
|
options.endpoint,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAC1B,8BAA4B;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n handleUserData(response.data.data, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAA0B;AAC1B,8BAA4B;AAmD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,eAAW,qCAAY;AAE7B,8BAAU,MAAM;AAOd,UAAM,uBAAuB,YAAY;AACvC,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAEhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAEX,cAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,UACxD,SAAS;AAAA,YACP,eAAe,UAAU,WAAW,KAAK;AAAA,UAC3C;AAAA,QACF,CAAC;AAED,gBAAQ,eAAe,SAAS,KAAK,IAAe;AACpD,+BAAuB,SAAS,KAAK,MAAM,QAAQ,kBAAkB;AACrE,uBAAe,SAAS,KAAK,MAAM,QAAQ,OAAO;AAClD,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAAA,MAC7D;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
|
|
@@ -26,6 +26,25 @@ var handleProfileSelection = (responseData, setSelectedProfile) => {
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
+
var handleUserData = (responseData, setUser) => {
|
|
30
|
+
if (!setUser) return;
|
|
31
|
+
if (!hasValidProfileData(responseData)) return;
|
|
32
|
+
const userId = responseData.userId;
|
|
33
|
+
const userName = responseData.userName;
|
|
34
|
+
const userEmail = responseData.userEmail;
|
|
35
|
+
if (userId) {
|
|
36
|
+
const userData = {
|
|
37
|
+
id: userId
|
|
38
|
+
};
|
|
39
|
+
if (userName) {
|
|
40
|
+
userData.name = userName;
|
|
41
|
+
}
|
|
42
|
+
if (userEmail) {
|
|
43
|
+
userData.email = userEmail;
|
|
44
|
+
}
|
|
45
|
+
setUser(userData);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
29
48
|
function useUrlAuthentication(options) {
|
|
30
49
|
const location = useLocation();
|
|
31
50
|
useEffect(() => {
|
|
@@ -46,6 +65,7 @@ function useUrlAuthentication(options) {
|
|
|
46
65
|
});
|
|
47
66
|
options.setSessionInfo(response.data.data);
|
|
48
67
|
handleProfileSelection(response.data.data, options.setSelectedProfile);
|
|
68
|
+
handleUserData(response.data.data, options.setUser);
|
|
49
69
|
options.clearParamsFromURL?.();
|
|
50
70
|
} catch (error) {
|
|
51
71
|
console.error("Erro ao obter informa\xE7\xF5es da sess\xE3o:", error);
|
|
@@ -56,6 +76,7 @@ function useUrlAuthentication(options) {
|
|
|
56
76
|
location.search,
|
|
57
77
|
options.setSessionInfo,
|
|
58
78
|
options.setSelectedProfile,
|
|
79
|
+
options.setUser,
|
|
59
80
|
options.setTokens,
|
|
60
81
|
options.api,
|
|
61
82
|
options.endpoint,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/Auth/useUrlAuthentication.ts"],"sourcesContent":["import { useEffect } from 'react';\nimport { useLocation } from 'react-router-dom';\n\n/**\n * Options interface for the useUrlAuthentication hook\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @interface UseUrlAuthOptions\n * @property {(tokens: Tokens) => void} setTokens - Function to set authentication tokens\n * @property {(session: Session) => void} setSessionInfo - Function to set session information\n * @property {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @property {(user: User) => void} [setUser] - Optional function to set user data\n * @property {object} api - API instance with get method\n * @property {(endpoint: string, config: unknown) => Promise<unknown>} api.get - API get method\n * @property {string} endpoint - API endpoint to fetch session data\n * @property {(searchParams: URLSearchParams) => object} [extractParams] - Custom parameter extraction function\n * @property {() => void} [clearParamsFromURL] - Function to clear URL parameters after processing\n */\nexport interface UseUrlAuthOptions<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n> {\n setTokens: (tokens: Tokens) => void;\n setSessionInfo: (session: Session) => void;\n setSelectedProfile?: (profile: Profile) => void;\n setUser?: (user: User) => void;\n api: { get: (endpoint: string, config: unknown) => Promise<unknown> };\n endpoint: string;\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n };\n clearParamsFromURL?: () => void;\n}\n\n/**\n * Helper function to extract authentication parameters from URL\n *\n * @param {object} location - Location object with search property\n * @param {string} location.search - URL search string\n * @param {function} [extractParams] - Custom parameter extraction function\n * @returns {object} Object with sessionId, token, and refreshToken\n *\n * @private\n */\nconst getAuthParams = (\n location: { search: string },\n extractParams?: (searchParams: URLSearchParams) => {\n sessionId: string;\n token: string;\n refreshToken: string;\n }\n) => {\n const searchParams = new URLSearchParams(location.search);\n return extractParams\n ? extractParams(searchParams)\n : {\n sessionId: searchParams.get('sessionId'),\n token: searchParams.get('token'),\n refreshToken: searchParams.get('refreshToken'),\n };\n};\n\n/**\n * Helper function to validate authentication parameters\n *\n * @param {object} authParams - Authentication parameters object\n * @param {string | null} authParams.sessionId - Session ID from URL\n * @param {string | null} authParams.token - Authentication token from URL\n * @param {string | null} authParams.refreshToken - Refresh token from URL\n * @returns {boolean} True if all required parameters are present\n *\n * @private\n */\nconst hasValidAuthParams = (authParams: {\n sessionId: string | null;\n token: string | null;\n refreshToken: string | null;\n}) => {\n return !!(\n authParams?.sessionId &&\n authParams?.token &&\n authParams?.refreshToken\n );\n};\n\n/**\n * Helper function to check if response has valid profile data\n *\n * @param {unknown} data - Response data to validate\n * @returns {data is Record<string, unknown>} Type guard for valid profile data\n *\n * @private\n */\nconst hasValidProfileData = (\n data: unknown\n): data is Record<string, unknown> => {\n return data !== null && typeof data === 'object' && data !== undefined;\n};\n\n/**\n * Helper function to handle profile selection from response data\n *\n * @template Profile - Profile type\n * @param {unknown} responseData - Response data from API\n * @param {(profile: Profile) => void} [setSelectedProfile] - Optional function to set selected profile\n * @returns {void}\n *\n * @private\n */\nconst handleProfileSelection = <Profile>(\n responseData: unknown,\n setSelectedProfile?: (profile: Profile) => void\n) => {\n if (!setSelectedProfile) return;\n if (!hasValidProfileData(responseData)) return;\n\n const profileId = responseData.profileId;\n const isValidProfileId = profileId !== null && profileId !== undefined;\n\n if (isValidProfileId) {\n setSelectedProfile({\n id: profileId,\n } as Profile);\n }\n};\n\n/**\n * Helper function to handle user data extraction from response data\n *\n * @template User - User type\n * @param {unknown} responseData - Response data from API\n * @param {(user: User) => void} [setUser] - Optional function to set user data\n * @returns {void}\n *\n * @private\n */\nconst handleUserData = <User>(\n responseData: unknown,\n setUser?: (user: User) => void\n) => {\n if (!setUser) return;\n if (!hasValidProfileData(responseData)) return;\n\n // Extrair dados do usuário da resposta da API\n const userId = responseData.userId;\n const userName = responseData.userName;\n const userEmail = responseData.userEmail;\n\n if (userId) {\n const userData: Record<string, unknown> = {\n id: userId,\n };\n\n if (userName) {\n userData.name = userName;\n }\n\n if (userEmail) {\n userData.email = userEmail;\n }\n\n // Adicionar outros campos conforme necessário\n setUser(userData as User);\n }\n};\n\n/**\n * Hook for handling URL-based authentication\n * Extracts authentication parameters from URL and processes them\n *\n * @template Tokens - Type for authentication tokens\n * @template Session - Type for session information\n * @template Profile - Type for profile information\n * @template User - Type for user information\n *\n * @param {UseUrlAuthOptions<Tokens, Session, Profile, User>} options - Configuration options\n * @returns {void}\n *\n * @example\n * ```typescript\n * useUrlAuthentication({\n * setTokens: (tokens) => authStore.setTokens(tokens),\n * setSessionInfo: (session) => authStore.setSessionInfo(session),\n * setSelectedProfile: (profile) => authStore.setProfile(profile),\n * setUser: (user) => authStore.setUser(user),\n * api: apiInstance,\n * endpoint: '/auth/session',\n * clearParamsFromURL: () => navigate('/', { replace: true })\n * });\n * ```\n */\nexport function useUrlAuthentication<\n Tokens = unknown,\n Session = unknown,\n Profile = unknown,\n User = unknown,\n>(options: UseUrlAuthOptions<Tokens, Session, Profile, User>) {\n const location = useLocation();\n\n useEffect(() => {\n /**\n * Main authentication handler that processes URL parameters\n *\n * @returns {Promise<void>}\n * @private\n */\n const handleAuthentication = async () => {\n const authParams = getAuthParams(location, options.extractParams);\n\n if (!hasValidAuthParams(authParams)) {\n return;\n }\n\n try {\n options.setTokens({\n token: authParams.token,\n refreshToken: authParams.refreshToken,\n } as Tokens);\n\n const response = (await options.api.get(options.endpoint, {\n headers: {\n Authorization: `Bearer ${authParams.token}`,\n },\n })) as { data: { data: unknown; [key: string]: unknown } };\n\n options.setSessionInfo(response.data.data as Session);\n handleProfileSelection(response.data.data, options.setSelectedProfile);\n handleUserData(response.data.data, options.setUser);\n options.clearParamsFromURL?.();\n } catch (error) {\n console.error('Erro ao obter informações da sessão:', error);\n }\n };\n\n handleAuthentication();\n }, [\n location.search,\n options.setSessionInfo,\n options.setSelectedProfile,\n options.setUser,\n options.setTokens,\n options.api,\n options.endpoint,\n options.extractParams,\n options.clearParamsFromURL,\n ]);\n}\n"],"mappings":";AAAA,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAmD5B,IAAM,gBAAgB,CACpB,UACA,kBAKG;AACH,QAAM,eAAe,IAAI,gBAAgB,SAAS,MAAM;AACxD,SAAO,gBACH,cAAc,YAAY,IAC1B;AAAA,IACE,WAAW,aAAa,IAAI,WAAW;AAAA,IACvC,OAAO,aAAa,IAAI,OAAO;AAAA,IAC/B,cAAc,aAAa,IAAI,cAAc;AAAA,EAC/C;AACN;AAaA,IAAM,qBAAqB,CAAC,eAItB;AACJ,SAAO,CAAC,EACN,YAAY,aACZ,YAAY,SACZ,YAAY;AAEhB;AAUA,IAAM,sBAAsB,CAC1B,SACoC;AACpC,SAAO,SAAS,QAAQ,OAAO,SAAS,YAAY,SAAS;AAC/D;AAYA,IAAM,yBAAyB,CAC7B,cACA,uBACG;AACH,MAAI,CAAC,mBAAoB;AACzB,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAExC,QAAM,YAAY,aAAa;AAC/B,QAAM,mBAAmB,cAAc,QAAQ,cAAc;AAE7D,MAAI,kBAAkB;AACpB,uBAAmB;AAAA,MACjB,IAAI;AAAA,IACN,CAAY;AAAA,EACd;AACF;AAYA,IAAM,iBAAiB,CACrB,cACA,YACG;AACH,MAAI,CAAC,QAAS;AACd,MAAI,CAAC,oBAAoB,YAAY,EAAG;AAGxC,QAAM,SAAS,aAAa;AAC5B,QAAM,WAAW,aAAa;AAC9B,QAAM,YAAY,aAAa;AAE/B,MAAI,QAAQ;AACV,UAAM,WAAoC;AAAA,MACxC,IAAI;AAAA,IACN;AAEA,QAAI,UAAU;AACZ,eAAS,OAAO;AAAA,IAClB;AAEA,QAAI,WAAW;AACb,eAAS,QAAQ;AAAA,IACnB;AAGA,YAAQ,QAAgB;AAAA,EAC1B;AACF;AA2BO,SAAS,qBAKd,SAA4D;AAC5D,QAAM,WAAW,YAAY;AAE7B,YAAU,MAAM;AAOd,UAAM,uBAAuB,YAAY;AACvC,YAAM,aAAa,cAAc,UAAU,QAAQ,aAAa;AAEhE,UAAI,CAAC,mBAAmB,UAAU,GAAG;AACnC;AAAA,MACF;AAEA,UAAI;AACF,gBAAQ,UAAU;AAAA,UAChB,OAAO,WAAW;AAAA,UAClB,cAAc,WAAW;AAAA,QAC3B,CAAW;AAEX,cAAM,WAAY,MAAM,QAAQ,IAAI,IAAI,QAAQ,UAAU;AAAA,UACxD,SAAS;AAAA,YACP,eAAe,UAAU,WAAW,KAAK;AAAA,UAC3C;AAAA,QACF,CAAC;AAED,gBAAQ,eAAe,SAAS,KAAK,IAAe;AACpD,+BAAuB,SAAS,KAAK,MAAM,QAAQ,kBAAkB;AACrE,uBAAe,SAAS,KAAK,MAAM,QAAQ,OAAO;AAClD,gBAAQ,qBAAqB;AAAA,MAC/B,SAAS,OAAO;AACd,gBAAQ,MAAM,iDAAwC,KAAK;AAAA,MAC7D;AAAA,IACF;AAEA,yBAAqB;AAAA,EACvB,GAAG;AAAA,IACD,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACH;","names":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '@/utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the badge\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_phosphor_react","import_phosphor_react","import_jsx_runtime","SIZE_CLASSES","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/components/MultipleChoice/MultipleChoice.tsx","../../src/components/CheckBox/CheckboxList.tsx","../../src/components/CheckBox/CheckBox.tsx","../../src/utils/utils.ts","../../src/components/Text/Text.tsx","../../src/components/Badge/Badge.tsx"],"sourcesContent":["import { HtmlHTMLAttributes, useEffect, useState } from 'react';\nimport CheckboxList, { CheckboxListItem } from '../CheckBox/CheckboxList';\nimport { cn } from '../../utils/utils';\nimport { CheckCircle, XCircle, Check } from 'phosphor-react';\nimport Badge from '../Badge/Badge';\n\ninterface Choice {\n value: string;\n label: string;\n status?: 'correct' | 'incorrect' | 'neutral';\n disabled?: boolean;\n}\n\ninterface MultipleChoiceListProps extends HtmlHTMLAttributes<HTMLDivElement> {\n choices: Choice[];\n disabled?: boolean;\n name?: string;\n selectedValues?: string[];\n onHandleSelectedValues?: (values: string[]) => void;\n mode?: 'interactive' | 'readonly';\n}\n\nconst MultipleChoiceList = ({\n disabled = false,\n className = '',\n choices,\n name,\n selectedValues,\n onHandleSelectedValues,\n mode = 'interactive',\n}: MultipleChoiceListProps) => {\n const [actualValue, setActualValue] = useState(selectedValues);\n\n useEffect(() => {\n setActualValue(selectedValues);\n }, [selectedValues]);\n const getStatusBadge = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return (\n <Badge variant=\"solid\" action=\"success\" iconLeft={<CheckCircle />}>\n Resposta correta\n </Badge>\n );\n case 'incorrect':\n return (\n <Badge variant=\"solid\" action=\"error\" iconLeft={<XCircle />}>\n Resposta incorreta\n </Badge>\n );\n default:\n return null;\n }\n };\n\n const getStatusStyles = (status: Choice['status']) => {\n switch (status) {\n case 'correct':\n return 'bg-success-background border-success-300';\n case 'incorrect':\n return 'bg-error-background border-error-300';\n default:\n return `bg-background border-border-100`;\n }\n };\n\n const renderVisualCheckbox = (isSelected: boolean, isDisabled: boolean) => {\n const checkboxClasses = cn(\n 'w-5 h-5 rounded border-2 cursor-default transition-all duration-200 flex items-center justify-center',\n isSelected\n ? 'border-primary-950 bg-primary-950 text-text'\n : 'border-border-400 bg-background',\n isDisabled && 'opacity-40 cursor-not-allowed'\n );\n\n return (\n <div className={checkboxClasses}>\n {isSelected && <Check size={16} weight=\"bold\" />}\n </div>\n );\n };\n\n if (mode === 'readonly') {\n return (\n <div className={cn('flex flex-col gap-2', className)}>\n {choices.map((choice, i) => {\n const isSelected = actualValue?.includes(choice.value) || false;\n const statusStyles = getStatusStyles(choice.status);\n const statusBadge = getStatusBadge(choice.status);\n\n return (\n <div\n key={`readonly-${choice.value}-${i}`}\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n statusStyles,\n choice.disabled ? 'opacity-50 cursor-not-allowed' : ''\n )}\n >\n <div className=\"flex items-center gap-2 flex-1\">\n {renderVisualCheckbox(isSelected, choice.disabled || disabled)}\n <span\n className={cn(\n 'flex-1',\n isSelected || (choice.status && choice.status != 'neutral')\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-default'\n )}\n >\n {choice.label}\n </span>\n </div>\n {statusBadge && (\n <div className=\"flex-shrink-0\">{statusBadge}</div>\n )}\n </div>\n );\n })}\n </div>\n );\n }\n return (\n <div\n className={cn(\n 'flex flex-row justify-between gap-2 items-start p-2 rounded-lg transition-all',\n disabled ? 'opacity-50 cursor-not-allowed' : '',\n className\n )}\n >\n <CheckboxList\n name={name}\n values={actualValue}\n onValuesChange={(v) => {\n setActualValue(v);\n onHandleSelectedValues?.(v);\n }}\n disabled={disabled}\n >\n {choices.map((choice, i) => (\n <div\n key={`interactive-${choice.value}-${i}`}\n className=\"flex flex-row gap-2 items-center\"\n >\n <CheckboxListItem\n value={choice.value}\n id={`interactive-${choice.value}-${i}`}\n disabled={choice.disabled || disabled}\n />\n\n <label\n htmlFor={`interactive-${choice.value}-${i}`}\n className={cn(\n 'flex-1',\n actualValue?.includes(choice.value)\n ? 'text-text-950'\n : 'text-text-600',\n choice.disabled || disabled\n ? 'cursor-not-allowed'\n : 'cursor-pointer'\n )}\n >\n {choice.label}\n </label>\n </div>\n ))}\n </CheckboxList>\n </div>\n );\n};\n\nexport { MultipleChoiceList };\n","import {\n InputHTMLAttributes,\n HTMLAttributes,\n ReactNode,\n forwardRef,\n useId,\n useEffect,\n useRef,\n Children,\n cloneElement,\n isValidElement,\n ReactElement,\n} from 'react';\nimport { create, StoreApi, useStore } from 'zustand';\nimport CheckBox from './CheckBox';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckboxList size variants\n */\ntype CheckboxListSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckboxList visual state\n */\ntype CheckboxListState =\n | 'default'\n | 'hovered'\n | 'focused'\n | 'invalid'\n | 'disabled';\n\n/**\n * CheckboxList store interface\n */\ninterface CheckboxListStore {\n values: string[];\n setValues: (values: string[]) => void;\n toggleValue: (value: string) => void;\n onValuesChange?: (values: string[]) => void;\n disabled: boolean;\n name: string;\n}\n\ntype CheckboxListStoreApi = StoreApi<CheckboxListStore>;\n\n/**\n * Create a new CheckboxList store\n */\nconst createCheckboxListStore = (\n name: string,\n defaultValues: string[],\n disabled: boolean,\n onValuesChange?: (values: string[]) => void\n): CheckboxListStoreApi =>\n create<CheckboxListStore>((set, get) => ({\n values: defaultValues,\n setValues: (values) => {\n if (!get().disabled) {\n set({ values });\n get().onValuesChange?.(values);\n }\n },\n toggleValue: (value) => {\n if (!get().disabled) {\n const currentValues = get().values;\n const newValues = currentValues.includes(value)\n ? currentValues.filter((v) => v !== value)\n : [...currentValues, value];\n set({ values: newValues });\n get().onValuesChange?.(newValues);\n }\n },\n onValuesChange,\n disabled,\n name,\n }));\n\n/**\n * Hook to access CheckboxList store\n */\nexport const useCheckboxListStore = (externalStore?: CheckboxListStoreApi) => {\n if (!externalStore) {\n throw new Error('CheckboxListItem must be used within a CheckboxList');\n }\n return externalStore;\n};\n\n/**\n * Inject store into CheckboxListItem children\n */\nconst injectStore = (\n children: ReactNode,\n store: CheckboxListStoreApi\n): ReactNode =>\n Children.map(children, (child) => {\n if (!isValidElement(child)) return child;\n const typedChild = child as ReactElement<CheckboxListItemProps>;\n const shouldInject = typedChild.type === CheckboxListItem;\n return cloneElement(typedChild, {\n ...(shouldInject ? { store } : {}),\n ...(typedChild.props.children\n ? { children: injectStore(typedChild.props.children, store) }\n : {}),\n });\n });\n\n/**\n * CheckboxList component props interface\n */\nexport type CheckboxListProps = {\n /** Current selected values */\n values?: string[];\n /** Default selected values for uncontrolled usage */\n defaultValues?: string[];\n /** Callback when selection changes */\n onValuesChange?: (values: string[]) => void;\n /** Group name for all checkboxes */\n name?: string;\n /** Disabled state for the entire group */\n disabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n /** Children components */\n children: ReactNode;\n} & Omit<HTMLAttributes<HTMLDivElement>, 'onChange' | 'defaultValues'>;\n\n/**\n * CheckboxList component for flexible checkbox group composition\n *\n * Uses Zustand for state management with automatic store injection.\n * Allows complete control over layout and styling by composing with CheckboxListItem.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]} onValuesChange={setValues}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option2\" id=\"c2\" />\n * <label htmlFor=\"c2\">Option 2</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxList = forwardRef<HTMLDivElement, CheckboxListProps>(\n (\n {\n values: propValues,\n defaultValues = [],\n onValuesChange,\n name: propName,\n disabled = false,\n className = '',\n children,\n ...props\n },\n ref\n ) => {\n // Generate unique name if not provided\n const generatedId = useId();\n const name = propName || `checkbox-list-${generatedId}`;\n\n // Create store reference\n const storeRef = useRef<CheckboxListStoreApi>(null);\n storeRef.current ??= createCheckboxListStore(\n name,\n defaultValues,\n disabled,\n onValuesChange\n );\n const store = storeRef.current;\n\n // Get store actions\n const { setValues } = useStore(store, (s) => s);\n\n // Call onValuesChange with initial values\n useEffect(() => {\n const currentValues = store.getState().values;\n if (currentValues.length > 0 && onValuesChange) {\n onValuesChange(currentValues);\n }\n }, []);\n\n // Handle controlled values changes\n useEffect(() => {\n if (propValues !== undefined) {\n setValues(propValues);\n }\n }, [propValues, setValues]);\n\n // Update disabled state\n useEffect(() => {\n store.setState({ disabled });\n }, [disabled, store]);\n\n return (\n <div\n ref={ref}\n className={cn('flex flex-col gap-2 w-full', className)}\n aria-label={name}\n {...props}\n >\n {injectStore(children, store)}\n </div>\n );\n }\n);\n\nCheckboxList.displayName = 'CheckboxList';\n\n/**\n * CheckboxListItem component props interface\n */\nexport type CheckboxListItemProps = {\n /** Value for this checkbox item */\n value: string;\n /** Store reference (automatically injected by CheckboxList) */\n store?: CheckboxListStoreApi;\n /** Disabled state for this specific item */\n disabled?: boolean;\n /** Size variant */\n size?: CheckboxListSize;\n /** Visual state */\n state?: CheckboxListState;\n /** Additional CSS classes */\n className?: string;\n} & Omit<\n InputHTMLAttributes<HTMLInputElement>,\n 'type' | 'name' | 'value' | 'checked' | 'onChange' | 'size'\n>;\n\n/**\n * CheckboxListItem component for use within CheckboxList\n *\n * A checkbox without label that works within CheckboxList context.\n * Provides just the checkbox input for maximum flexibility in composition.\n *\n * @example\n * ```tsx\n * <CheckboxList defaultValues={[\"option1\"]}>\n * <div className=\"flex items-center gap-3\">\n * <CheckboxListItem value=\"option1\" id=\"c1\" />\n * <label htmlFor=\"c1\">Option 1</label>\n * </div>\n * </CheckboxList>\n * ```\n */\nconst CheckboxListItem = forwardRef<HTMLInputElement, CheckboxListItemProps>(\n (\n {\n value,\n store: externalStore,\n disabled: itemDisabled,\n size = 'medium',\n state = 'default',\n className = '',\n id,\n ...props\n },\n ref\n ) => {\n // Get store and state\n const store = useCheckboxListStore(externalStore);\n const {\n values: groupValues,\n toggleValue,\n disabled: groupDisabled,\n name,\n } = useStore(store);\n\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-item-${generatedId}`;\n\n // Determine states\n const isChecked = groupValues.includes(value);\n const isDisabled = groupDisabled || itemDisabled;\n const currentState = isDisabled ? 'disabled' : state;\n\n // Use standard CheckBox component for consistency and simplicity\n return (\n <CheckBox\n ref={ref}\n id={inputId}\n name={name}\n value={value}\n checked={isChecked}\n disabled={isDisabled}\n size={size}\n state={currentState}\n className={className}\n onChange={() => {\n if (!isDisabled) {\n toggleValue(value);\n }\n }}\n {...props}\n />\n );\n }\n);\n\nCheckboxListItem.displayName = 'CheckboxListItem';\n\nexport default CheckboxList;\nexport { CheckboxListItem };\n","import {\n InputHTMLAttributes,\n ReactNode,\n forwardRef,\n useState,\n useId,\n ChangeEvent,\n} from 'react';\nimport Text from '../Text/Text';\nimport { Check, Minus } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * CheckBox size variants\n */\ntype CheckBoxSize = 'small' | 'medium' | 'large';\n\n/**\n * CheckBox visual state\n */\ntype CheckBoxState = 'default' | 'hovered' | 'focused' | 'invalid' | 'disabled';\n\n/**\n * Size configurations using Tailwind classes\n */\nconst SIZE_CLASSES = {\n small: {\n checkbox: 'w-4 h-4', // 16px x 16px\n textSize: 'sm' as const,\n spacing: 'gap-1.5', // 6px\n borderWidth: 'border-2',\n iconSize: 14, // pixels for Phosphor icons\n labelHeight: 'h-[21px]',\n },\n medium: {\n checkbox: 'w-5 h-5', // 20px x 20px\n textSize: 'md' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-2',\n iconSize: 16, // pixels for Phosphor icons\n labelHeight: 'h-6',\n },\n large: {\n checkbox: 'w-6 h-6', // 24px x 24px\n textSize: 'lg' as const,\n spacing: 'gap-2', // 8px\n borderWidth: 'border-[3px]', // 3px border\n iconSize: 20, // pixels for Phosphor icons\n labelHeight: 'h-[27px]',\n },\n} as const;\n\n/**\n * Base checkbox styling classes using design system colors\n */\nconst BASE_CHECKBOX_CLASSES =\n 'rounded border cursor-pointer transition-all duration-200 flex items-center justify-center focus:outline-none';\n\n/**\n * State-based styling classes using design system colors from styles.css\n */\nconst STATE_CLASSES = {\n default: {\n unchecked: 'border-border-400 bg-background hover:border-border-500',\n checked:\n 'border-primary-950 bg-primary-950 text-text hover:border-primary-800 hover:bg-primary-800',\n },\n hovered: {\n unchecked: 'border-border-500 bg-background',\n checked: 'border-primary-800 bg-primary-800 text-text',\n },\n focused: {\n unchecked:\n 'border-indicator-info bg-background ring-2 ring-indicator-info/20',\n checked:\n 'border-indicator-info bg-primary-950 text-text ring-2 ring-indicator-info/20',\n },\n invalid: {\n unchecked: 'border-error-700 bg-background hover:border-error-600',\n checked: 'border-error-700 bg-primary-950 text-text',\n },\n disabled: {\n unchecked: 'border-border-400 bg-background cursor-not-allowed opacity-40',\n checked:\n 'border-primary-600 bg-primary-600 text-text cursor-not-allowed opacity-40',\n },\n} as const;\n\n/**\n * CheckBox component props interface\n */\nexport type CheckBoxProps = {\n /** Label text to display next to the checkbox */\n label?: ReactNode;\n /** Size variant of the checkbox */\n size?: CheckBoxSize;\n /** Visual state of the checkbox */\n state?: CheckBoxState;\n /** Indeterminate state for partial selections */\n indeterminate?: boolean;\n /** Error message to display */\n errorMessage?: string;\n /** Helper text to display */\n helperText?: string;\n /** Additional CSS classes */\n className?: string;\n /** Label CSS classes */\n labelClassName?: string;\n} & Omit<InputHTMLAttributes<HTMLInputElement>, 'size' | 'type'>;\n\n/**\n * CheckBox component for Analytica Ensino platforms\n *\n * A checkbox component with essential states, sizes and themes.\n * Uses the Analytica Ensino Design System colors from styles.css with automatic\n * light/dark mode support. Includes Text component integration for consistent typography.\n *\n * @example\n * ```tsx\n * // Basic checkbox\n * <CheckBox label=\"Option\" />\n *\n * // Small size\n * <CheckBox size=\"small\" label=\"Small option\" />\n *\n * // Invalid state\n * <CheckBox state=\"invalid\" label=\"Required field\" />\n *\n * // Disabled state\n * <CheckBox disabled label=\"Disabled option\" />\n * ```\n */\nconst CheckBox = forwardRef<HTMLInputElement, CheckBoxProps>(\n (\n {\n label,\n size = 'medium',\n state = 'default',\n indeterminate = false,\n errorMessage,\n helperText,\n className = '',\n labelClassName = '',\n checked: checkedProp,\n disabled,\n id,\n onChange,\n ...props\n },\n ref\n ) => {\n // Generate unique ID if not provided\n const generatedId = useId();\n const inputId = id ?? `checkbox-${generatedId}`;\n\n // Handle controlled vs uncontrolled behavior\n const [internalChecked, setInternalChecked] = useState(false);\n const isControlled = checkedProp !== undefined;\n const checked = isControlled ? checkedProp : internalChecked;\n\n // Handle change events\n const handleChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (!isControlled) {\n setInternalChecked(event.target.checked);\n }\n onChange?.(event);\n };\n\n // Determine current state based on props\n const currentState = disabled ? 'disabled' : state;\n\n // Get size classes\n const sizeClasses = SIZE_CLASSES[size];\n\n // Determine checkbox visual variant\n const checkVariant = checked || indeterminate ? 'checked' : 'unchecked';\n\n // Get styling classes\n const stylingClasses = STATE_CLASSES[currentState][checkVariant];\n\n // Special border width handling for focused/hovered states and large size\n const borderWidthClass =\n state === 'focused' || (state === 'hovered' && size === 'large')\n ? 'border-[3px]'\n : sizeClasses.borderWidth;\n\n // Get final checkbox classes\n const checkboxClasses = cn(\n BASE_CHECKBOX_CLASSES,\n sizeClasses.checkbox,\n borderWidthClass,\n stylingClasses,\n className\n );\n\n // Render appropriate icon based on state\n const renderIcon = () => {\n if (indeterminate) {\n return (\n <Minus\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n if (checked) {\n return (\n <Check\n size={sizeClasses.iconSize}\n weight=\"bold\"\n color=\"currentColor\"\n />\n );\n }\n\n return null;\n };\n\n return (\n <div className=\"flex flex-col\">\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.spacing,\n disabled ? 'opacity-40' : ''\n )}\n >\n {/* Hidden native input for accessibility and form submission */}\n <input\n ref={ref}\n type=\"checkbox\"\n id={inputId}\n checked={checked}\n disabled={disabled}\n onChange={handleChange}\n className=\"sr-only\"\n {...props}\n />\n\n {/* Custom styled checkbox */}\n <label htmlFor={inputId} className={checkboxClasses}>\n {/* Show appropriate icon based on state */}\n {renderIcon()}\n </label>\n\n {/* Label text */}\n {label && (\n <div\n className={cn(\n 'flex flex-row items-center',\n sizeClasses.labelHeight\n )}\n >\n <Text\n as=\"label\"\n htmlFor={inputId}\n size={sizeClasses.textSize}\n weight=\"normal\"\n className={cn(\n 'cursor-pointer select-none leading-[150%] flex items-center font-roboto',\n labelClassName\n )}\n >\n {label}\n </Text>\n </div>\n )}\n </div>\n\n {/* Error message */}\n {errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-error-600\"\n >\n {errorMessage}\n </Text>\n )}\n\n {/* Helper text */}\n {helperText && !errorMessage && (\n <Text\n size=\"sm\"\n weight=\"normal\"\n className=\"mt-1.5\"\n color=\"text-text-500\"\n >\n {helperText}\n </Text>\n )}\n </div>\n );\n }\n);\n\nCheckBox.displayName = 'CheckBox';\n\nexport default CheckBox;\n","import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Base text component props\n */\ntype BaseTextProps = {\n /** Content to be displayed */\n children?: ReactNode;\n /** Text size variant */\n size?:\n | '2xs'\n | 'xs'\n | 'sm'\n | 'md'\n | 'lg'\n | 'xl'\n | '2xl'\n | '3xl'\n | '4xl'\n | '5xl'\n | '6xl';\n /** Font weight variant */\n weight?:\n | 'hairline'\n | 'light'\n | 'normal'\n | 'medium'\n | 'semibold'\n | 'bold'\n | 'extrabold'\n | 'black';\n /** Color variant - white for light backgrounds, black for dark backgrounds */\n color?: string;\n /** Additional CSS classes to apply */\n className?: string;\n};\n\n/**\n * Polymorphic text component props that ensures type safety based on the 'as' prop\n */\ntype TextProps<T extends ElementType = 'p'> = BaseTextProps & {\n /** HTML tag to render */\n as?: T;\n} & Omit<ComponentPropsWithoutRef<T>, keyof BaseTextProps>;\n\n/**\n * Text component for Analytica Ensino platforms\n *\n * A flexible polymorphic text component with multiple sizes, weights, and colors.\n * Automatically adapts to dark and light themes with full type safety.\n *\n * @param children - The content to display\n * @param size - The text size variant (2xs, xs, sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl, 6xl)\n * @param weight - The font weight variant (hairline, light, normal, medium, semibold, bold, extrabold, black)\n * @param color - The color variant - adapts to theme\n * @param as - The HTML tag to render - determines allowed attributes via TypeScript\n * @param className - Additional CSS classes\n * @param props - HTML attributes valid for the chosen tag only\n * @returns A styled text element with type-safe attributes\n *\n * @example\n * ```tsx\n * <Text size=\"lg\" weight=\"bold\" color=\"text-info-800\">\n * This is a large, bold text\n * </Text>\n *\n * <Text as=\"a\" href=\"/link\" target=\"_blank\">\n * Link with type-safe anchor attributes\n * </Text>\n *\n * <Text as=\"button\" onClick={handleClick} disabled>\n * Button with type-safe button attributes\n * </Text>\n * ```\n */\nconst Text = <T extends ElementType = 'p'>({\n children,\n size = 'md',\n weight = 'normal',\n color = 'text-text-950',\n as,\n className = '',\n ...props\n}: TextProps<T>) => {\n let sizeClasses = '';\n let weightClasses = '';\n\n // Text size classes mapping\n const sizeClassMap = {\n '2xs': 'text-2xs',\n xs: 'text-xs',\n sm: 'text-sm',\n md: 'text-md',\n lg: 'text-lg',\n xl: 'text-xl',\n '2xl': 'text-2xl',\n '3xl': 'text-3xl',\n '4xl': 'text-4xl',\n '5xl': 'text-5xl',\n '6xl': 'text-6xl',\n } as const;\n\n sizeClasses = sizeClassMap[size] ?? sizeClassMap.md;\n\n // Font weight classes mapping\n const weightClassMap = {\n hairline: 'font-hairline',\n light: 'font-light',\n normal: 'font-normal',\n medium: 'font-medium',\n semibold: 'font-semibold',\n bold: 'font-bold',\n extrabold: 'font-extrabold',\n black: 'font-black',\n } as const;\n\n weightClasses = weightClassMap[weight] ?? weightClassMap.normal;\n\n const baseClasses = 'font-primary';\n const Component = as ?? ('p' as ElementType);\n\n return (\n <Component\n className={cn(baseClasses, sizeClasses, weightClasses, color, className)}\n {...props}\n >\n {children}\n </Component>\n );\n};\n\nexport default Text;\n","import { HTMLAttributes, ReactNode } from 'react';\nimport { Bell } from 'phosphor-react';\nimport { cn } from '../../utils/utils';\n\n/**\n * Lookup table for variant and action class combinations\n */\nconst VARIANT_ACTION_CLASSES = {\n solid: {\n error: 'bg-error-background text-error-700 focus-visible:outline-none',\n warning: 'bg-warning text-warning-800 focus-visible:outline-none',\n success: 'bg-success text-success-800 focus-visible:outline-none',\n info: 'bg-info text-info-800 focus-visible:outline-none',\n muted: 'bg-background-muted text-background-800 focus-visible:outline-none',\n },\n outlined: {\n error:\n 'bg-error text-error-700 border border-error-300 focus-visible:outline-none',\n warning:\n 'bg-warning text-warning-800 border border-warning-300 focus-visible:outline-none',\n success:\n 'bg-success text-success-800 border border-success-300 focus-visible:outline-none',\n info: 'bg-info text-info-800 border border-info-300 focus-visible:outline-none',\n muted:\n 'bg-background-muted text-background-800 border border-border-300 focus-visible:outline-none',\n },\n exams: {\n exam1: 'bg-exam-1 text-info-700 focus-visible:outline-none',\n exam2: 'bg-exam-2 text-typography-1 focus-visible:outline-none',\n exam3: 'bg-exam-3 text-typography-2 focus-visible:outline-none',\n exam4: 'bg-exam-4 text-success-700 focus-visible:outline-none',\n },\n examsOutlined: {\n exam1:\n 'bg-exam-1 text-info-700 border border-info-700 focus-visible:outline-none',\n exam2:\n 'bg-exam-2 text-typography-1 border border-typography-1 focus-visible:outline-none',\n exam3:\n 'bg-exam-3 text-typography-2 border border-typography-2 focus-visible:outline-none',\n exam4:\n 'bg-exam-4 text-success-700 border border-success-700 focus-visible:outline-none',\n },\n resultStatus: {\n negative: 'bg-error text-error-800 focus-visible:outline-none',\n positive: 'bg-success text-success-800 focus-visible:outline-none',\n },\n notification: 'text-primary',\n} as const;\n\n/**\n * Lookup table for size classes\n */\nconst SIZE_CLASSES = {\n small: 'text-2xs px-2 py-1',\n medium: 'text-xs px-2 py-1',\n large: 'text-sm px-2 py-1',\n} as const;\n\nconst SIZE_CLASSES_ICON = {\n small: 'size-3',\n medium: 'size-3.5',\n large: 'size-4',\n} as const;\n\n/**\n * Badge component props interface\n */\ntype BadgeProps = {\n /** Content to be displayed inside the badge */\n children?: ReactNode;\n /** Ícone à direita do texto */\n iconRight?: ReactNode;\n /** Ícone à esquerda do texto */\n iconLeft?: ReactNode;\n /** Size of the badge */\n size?: 'small' | 'medium' | 'large';\n /** Visual variant of the badge */\n variant?:\n | 'solid'\n | 'outlined'\n | 'exams'\n | 'examsOutlined'\n | 'resultStatus'\n | 'notification';\n /** Action type of the badge */\n action?:\n | 'error'\n | 'warning'\n | 'success'\n | 'info'\n | 'muted'\n | 'exam1'\n | 'exam2'\n | 'exam3'\n | 'exam4'\n | 'positive'\n | 'negative';\n /** Additional CSS classes to apply */\n className?: string;\n notificationActive?: boolean;\n} & HTMLAttributes<HTMLDivElement>;\n\n/**\n * Badge component for Analytica Ensino platforms\n *\n * A flexible button component with multiple variants, sizes and actions.\n *\n * @param children - The content to display inside the badge\n * @param size - The size variant (extra-small, small, medium, large, extra-large)\n * @param variant - The visual style variant (solid, outline, link)\n * @param action - The action type (primary, positive, negative)\n * @param className - Additional CSS classes\n * @param props - All other standard div HTML attributes\n * @returns A styled badge element\n *\n * @example\n * ```tsx\n * <Badge variant=\"solid\" action=\"info\" size=\"medium\">\n * Information\n * </Badge>\n * ```\n */\nconst Badge = ({\n children,\n iconLeft,\n iconRight,\n size = 'medium',\n variant = 'solid',\n action = 'error',\n className = '',\n notificationActive = false,\n ...props\n}: BadgeProps) => {\n // Get classes from lookup tables\n const sizeClasses = SIZE_CLASSES[size];\n const sizeClassesIcon = SIZE_CLASSES_ICON[size];\n const variantActionMap = VARIANT_ACTION_CLASSES[variant] || {};\n const variantClasses =\n typeof variantActionMap === 'string'\n ? variantActionMap\n : ((variantActionMap as Record<string, string>)[action] ??\n (variantActionMap as Record<string, string>).muted ??\n '');\n\n const baseClasses =\n 'inline-flex items-center justify-center rounded-xs font-normal gap-1 relative';\n\n const baseClassesIcon = 'flex items-center';\n if (variant === 'notification') {\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n <Bell size={24} className=\"text-current\" aria-hidden=\"true\" />\n\n {notificationActive && (\n <span\n data-testid=\"notification-dot\"\n className=\"absolute top-[5px] right-[10px] block h-2 w-2 rounded-full bg-indicator-error ring-2 ring-white\"\n />\n )}\n </div>\n );\n }\n return (\n <div\n className={cn(baseClasses, variantClasses, sizeClasses, className)}\n {...props}\n >\n {iconLeft && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>{iconLeft}</span>\n )}\n {children}\n {iconRight && (\n <span className={cn(baseClassesIcon, sizeClassesIcon)}>\n {iconRight}\n </span>\n )}\n </div>\n );\n};\n\nexport default Badge;\n"],"mappings":"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","names":["import_react","import_react","import_jsx_runtime","import_jsx_runtime","import_phosphor_react","import_phosphor_react","import_jsx_runtime","SIZE_CLASSES","import_jsx_runtime"]}
|