kitunga-web 0.1.98 → 0.1.100
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/features/data-display/components/Badges/CheckBadge/CheckBadge.d.ts +16 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.d.ts.map +1 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.js +14 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.js.map +1 -0
- package/dist/features/data-display/components/Badges/CheckBadge/CheckBadge.module.css +29 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.d.ts +19 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.d.ts.map +1 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.js +33 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.js.map +1 -0
- package/dist/features/data-display/components/Tabs/SubTabs/SubTabs.module.css +64 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.d.ts +25 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.d.ts.map +1 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.js +35 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.js.map +1 -0
- package/dist/features/data-display/components/Tabs/Tabs/Tabs.module.css +85 -0
- package/dist/features/inputs/components/Inputs/Checkbox.d.ts +17 -0
- package/dist/features/inputs/components/Inputs/Checkbox.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/Checkbox.js +16 -0
- package/dist/features/inputs/components/Inputs/Checkbox.js.map +1 -0
- package/dist/features/inputs/components/Inputs/Checkbox.module.css +68 -0
- package/dist/features/inputs/components/Inputs/FormLabel.d.ts +12 -0
- package/dist/features/inputs/components/Inputs/FormLabel.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/FormLabel.js +10 -0
- package/dist/features/inputs/components/Inputs/FormLabel.js.map +1 -0
- package/dist/features/inputs/components/Inputs/FormLabel.module.css +23 -0
- package/dist/features/inputs/components/Inputs/RadioButton.d.ts +13 -0
- package/dist/features/inputs/components/Inputs/RadioButton.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/RadioButton.js +9 -0
- package/dist/features/inputs/components/Inputs/RadioButton.js.map +1 -0
- package/dist/features/inputs/components/Inputs/RadioButton.module.css +66 -0
- package/dist/features/inputs/components/Inputs/Toggle.d.ts +12 -0
- package/dist/features/inputs/components/Inputs/Toggle.d.ts.map +1 -0
- package/dist/features/inputs/components/Inputs/Toggle.js +8 -0
- package/dist/features/inputs/components/Inputs/Toggle.js.map +1 -0
- package/dist/features/inputs/components/Inputs/Toggle.module.css +62 -0
- package/dist/features/patterns/components/Form/VerificationCodeStep/VerificationCodeStep.d.ts +9 -1
- package/dist/features/patterns/components/Form/VerificationCodeStep/VerificationCodeStep.d.ts.map +1 -1
- package/dist/features/patterns/components/Form/VerificationCodeStep/VerificationCodeStep.js +4 -4
- package/dist/features/patterns/components/Form/VerificationCodeStep/VerificationCodeStep.js.map +1 -1
- package/dist/features/selects/components/PickerSelect/PickerSelect.d.ts +94 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.d.ts.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.js +137 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.js.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSelect.module.css +228 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.d.ts +51 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.d.ts.map +1 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.js +65 -0
- package/dist/features/selects/components/PickerSelect/PickerSheet.js.map +1 -0
- package/dist/features/selects/components/{Selects → PickerSelect}/pickerOptions.d.ts +18 -3
- package/dist/features/selects/components/PickerSelect/pickerOptions.d.ts.map +1 -0
- package/dist/features/selects/components/{Selects → PickerSelect}/pickerOptions.js +4 -4
- package/dist/features/selects/components/PickerSelect/pickerOptions.js.map +1 -0
- package/dist/features/selects/components/Selects/CustomSelect.d.ts +1 -51
- package/dist/features/selects/components/Selects/CustomSelect.d.ts.map +1 -1
- package/dist/features/selects/components/Selects/CustomSelect.js +34 -140
- package/dist/features/selects/components/Selects/CustomSelect.js.map +1 -1
- package/dist/features/selects/components/Selects/CustomSelect.module.css +0 -127
- package/dist/shared/styles/tokens.css +11 -0
- package/dist/ui.d.ts +20 -0
- package/dist/ui.d.ts.map +1 -1
- package/dist/ui.js +10 -0
- package/dist/ui.js.map +1 -1
- package/package.json +1 -1
- package/dist/features/selects/components/Selects/pickerOptions.d.ts.map +0 -1
- package/dist/features/selects/components/Selects/pickerOptions.js.map +0 -1
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export interface CheckBadgeProps {
|
|
2
|
+
checked: boolean;
|
|
3
|
+
/** 'corner' — bolha absoluta no canto inferior-direito do avatar
|
|
4
|
+
* (o pai tem de ser position:relative). 'inline' — elemento em
|
|
5
|
+
* fluxo normal, para o fim de uma linha de lista/picker. */
|
|
6
|
+
placement?: 'corner' | 'inline';
|
|
7
|
+
/** Fundo da bolha quando NÃO está seleccionada (ex.: 'var(--bg-primary)'
|
|
8
|
+
* quando assenta sobre o avatar). Por omissão é transparente. */
|
|
9
|
+
uncheckedBg?: string;
|
|
10
|
+
/** Cor do anel quando seleccionada (ex.: 'var(--bg-primary)' para o anel
|
|
11
|
+
* branco tipo bola de online). Por omissão usa o azul do fundo. */
|
|
12
|
+
checkedBorderColor?: string;
|
|
13
|
+
className?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare function CheckBadge({ checked, placement, uncheckedBg, checkedBorderColor, className, }: CheckBadgeProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
//# sourceMappingURL=CheckBadge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckBadge.d.ts","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Badges/CheckBadge/CheckBadge.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB;;iEAE6D;IAC7D,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC;sEACkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;wEACoE;IACpE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,SAAoB,EACpB,WAAW,EACX,kBAAkB,EAClB,SAAc,GACf,EAAE,eAAe,2CAgBjB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Check } from 'lucide-react';
|
|
3
|
+
import styles from './CheckBadge.module.css';
|
|
4
|
+
// Bolha de selecção — o padrão "bola de online": anel azul em repouso,
|
|
5
|
+
// azul cheia + check branco quando marcada. O clique fica no item pai.
|
|
6
|
+
export function CheckBadge({ checked, placement = 'corner', uncheckedBg, checkedBorderColor, className = '', }) {
|
|
7
|
+
const style = {
|
|
8
|
+
'--badge-unchecked-bg': uncheckedBg,
|
|
9
|
+
'--badge-checked-border': checkedBorderColor,
|
|
10
|
+
};
|
|
11
|
+
const hasStyle = uncheckedBg !== undefined || checkedBorderColor !== undefined;
|
|
12
|
+
return (_jsx("span", { className: `${styles.badge} ${checked ? styles.checked : ''} ${placement === 'inline' ? styles.inline : ''} ${className}`, style: hasStyle ? style : undefined, "aria-hidden": "true", children: checked && _jsx(Check, { size: 13, strokeWidth: 3 }) }));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=CheckBadge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CheckBadge.js","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Badges/CheckBadge/CheckBadge.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAiB7C,uEAAuE;AACvE,uEAAuE;AACvE,MAAM,UAAU,UAAU,CAAC,EACzB,OAAO,EACP,SAAS,GAAG,QAAQ,EACpB,WAAW,EACX,kBAAkB,EAClB,SAAS,GAAG,EAAE,GACE;IAChB,MAAM,KAAK,GAAG;QACZ,sBAAsB,EAAE,WAAW;QACnC,wBAAwB,EAAE,kBAAkB;KAC5B,CAAC;IACnB,MAAM,QAAQ,GAAG,WAAW,KAAK,SAAS,IAAI,kBAAkB,KAAK,SAAS,CAAC;IAE/E,OAAO,CACL,eACE,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,EACzH,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,iBACvB,MAAM,YAEjB,OAAO,IAAI,KAAC,KAAK,IAAC,IAAI,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,GAAI,GAC1C,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/* Bolha de selecção — o padrão "bola de online". O default é a bolha
|
|
2
|
+
absoluta no canto do avatar; 'inline' senta no fluxo (fim de linha). */
|
|
3
|
+
.badge {
|
|
4
|
+
position: absolute;
|
|
5
|
+
bottom: -2px;
|
|
6
|
+
right: -2px;
|
|
7
|
+
width: 22px;
|
|
8
|
+
height: 22px;
|
|
9
|
+
border-radius: 50%;
|
|
10
|
+
background: var(--badge-unchecked-bg, transparent);
|
|
11
|
+
border: 2px solid var(--bg-interactive);
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: center;
|
|
15
|
+
color: var(--text-on-primary);
|
|
16
|
+
z-index: 2;
|
|
17
|
+
transition: all var(--transition-fast);
|
|
18
|
+
pointer-events: none;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.badge.inline {
|
|
22
|
+
position: static;
|
|
23
|
+
flex-shrink: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.badge.checked {
|
|
27
|
+
background: var(--bg-interactive);
|
|
28
|
+
border-color: var(--badge-checked-border, var(--bg-interactive));
|
|
29
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SubTabItem {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
/** Marcador numérico — só onde o número responde "quantas coisas me
|
|
5
|
+
esperam" (filas de atenção); listas/filtros nunca o usam. */
|
|
6
|
+
count?: number;
|
|
7
|
+
}
|
|
8
|
+
export interface SubTabsProps {
|
|
9
|
+
items: SubTabItem[];
|
|
10
|
+
activeId: string;
|
|
11
|
+
onSelect: (id: string) => void;
|
|
12
|
+
/** 'scroll' = com padding próprio; 'nopad' = sem padding, para usar
|
|
13
|
+
dentro de uma barra exterior. */
|
|
14
|
+
variant?: 'scroll' | 'nopad';
|
|
15
|
+
className?: string;
|
|
16
|
+
ariaLabel?: string;
|
|
17
|
+
}
|
|
18
|
+
export default function SubTabs({ items, activeId, onSelect, variant, className, ariaLabel }: SubTabsProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
//# sourceMappingURL=SubTabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubTabs.d.ts","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Tabs/SubTabs/SubTabs.tsx"],"names":[],"mappings":"AAKA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd;oEACgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B;wCACoC;IACpC,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,CAAC,OAAO,UAAU,OAAO,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAkB,EAAE,SAAc,EAAE,SAAS,EAAE,EAAE,YAAY,2CA8CzH"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import styles from './SubTabs.module.css';
|
|
5
|
+
// Sub-tabs — pills arredondadas com o activo em azul claro
|
|
6
|
+
// (--selection-bg/--selection-text) e scroll-x quando não cabem.
|
|
7
|
+
export default function SubTabs({ items, activeId, onSelect, variant = 'scroll', className = '', ariaLabel }) {
|
|
8
|
+
const containerClass = variant === 'nopad' ? styles.subTabsScrollNoPad : styles.subTabsScroll;
|
|
9
|
+
const containerRef = useRef(null);
|
|
10
|
+
// Igual aos Tabs principais — o pill activo nunca fica cortado nem
|
|
11
|
+
// encostado à borda: o cálculo manual soma o padding real do contentor.
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
const container = containerRef.current;
|
|
14
|
+
const activeEl = container === null || container === void 0 ? void 0 : container.querySelector('[data-active="true"]');
|
|
15
|
+
if (!container || !activeEl)
|
|
16
|
+
return;
|
|
17
|
+
const cs = getComputedStyle(container);
|
|
18
|
+
const padL = parseFloat(cs.paddingLeft) || 0;
|
|
19
|
+
const padR = parseFloat(cs.paddingRight) || 0;
|
|
20
|
+
const elRect = activeEl.getBoundingClientRect();
|
|
21
|
+
const cRect = container.getBoundingClientRect();
|
|
22
|
+
const overRight = elRect.right + padR - cRect.right;
|
|
23
|
+
const overLeft = cRect.left + padL - elRect.left;
|
|
24
|
+
if (overRight > 0) {
|
|
25
|
+
container.scrollTo({ left: container.scrollLeft + overRight, behavior: 'smooth' });
|
|
26
|
+
}
|
|
27
|
+
else if (overLeft > 0) {
|
|
28
|
+
container.scrollTo({ left: container.scrollLeft - overLeft, behavior: 'smooth' });
|
|
29
|
+
}
|
|
30
|
+
}, [activeId]);
|
|
31
|
+
return (_jsx("div", { className: `${containerClass} ${className}`, ref: containerRef, role: "tablist", "aria-label": ariaLabel, children: items.map((t) => (_jsxs("button", { type: "button", role: "tab", "aria-selected": activeId === t.id, onClick: () => onSelect(t.id), className: styles.subTab, "data-active": activeId === t.id, children: [t.label, t.count !== undefined && t.count > 0 && (_jsx("span", { className: `${styles.subTabCount} ${activeId === t.id ? styles.activeSubTabCount : ''}`, children: t.count }))] }, t.id))) }));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=SubTabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SubTabs.js","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Tabs/SubTabs/SubTabs.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
.subTab {
|
|
2
|
+
padding: 6px 12px;
|
|
3
|
+
border-radius: var(--radius-full);
|
|
4
|
+
border: 1px solid var(--border-divider);
|
|
5
|
+
background: var(--bg-primary);
|
|
6
|
+
color: var(--text-secondary);
|
|
7
|
+
cursor: pointer;
|
|
8
|
+
font-size: 0.85rem;
|
|
9
|
+
|
|
10
|
+
white-space: nowrap;
|
|
11
|
+
transition: all 0.2s ease;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.subTab[data-active='true'] {
|
|
15
|
+
background: var(--selection-bg);
|
|
16
|
+
color: var(--selection-text);
|
|
17
|
+
border-color: rgba(36, 90, 223, 0.35);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/* Count — o mesmo padrão do .tabCount das Tabs principais: cinza em
|
|
21
|
+
repouso, primário na pill activa. */
|
|
22
|
+
.subTabCount {
|
|
23
|
+
background-color: var(--color-gray-200);
|
|
24
|
+
color: var(--text-secondary);
|
|
25
|
+
border-radius: 12px;
|
|
26
|
+
padding: 1px 7px;
|
|
27
|
+
font-size: 11px;
|
|
28
|
+
font-weight: 500;
|
|
29
|
+
margin-left: 5px;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.activeSubTabCount {
|
|
33
|
+
background-color: var(--color-primary-light);
|
|
34
|
+
color: var(--color-white);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.subTabsScroll {
|
|
38
|
+
display: flex;
|
|
39
|
+
gap: 8px;
|
|
40
|
+
padding: 16px var(--spacing-md);
|
|
41
|
+
overflow-x: auto;
|
|
42
|
+
white-space: nowrap;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.subTabsScrollNoPad {
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: 8px;
|
|
48
|
+
overflow-x: auto;
|
|
49
|
+
white-space: nowrap;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/* Touch — o dedo faz o scroll; a thumb não é necessária (invisível).
|
|
53
|
+
O scroll continua funcional, só a barra desaparece. */
|
|
54
|
+
@media (pointer: coarse) {
|
|
55
|
+
.subTabsScroll,
|
|
56
|
+
.subTabsScrollNoPad {
|
|
57
|
+
scrollbar-width: none;
|
|
58
|
+
-ms-overflow-style: none;
|
|
59
|
+
}
|
|
60
|
+
.subTabsScroll::-webkit-scrollbar,
|
|
61
|
+
.subTabsScrollNoPad::-webkit-scrollbar {
|
|
62
|
+
display: none;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface TabsItem {
|
|
3
|
+
id: string;
|
|
4
|
+
/** ReactNode — quem precisa de ícone/label separados (ex.: colapsar o
|
|
5
|
+
texto no mobile) passa JSX; uma string continua a funcionar. */
|
|
6
|
+
label: React.ReactNode;
|
|
7
|
+
/** Ícone à esquerda do texto — gap pequeno (ver .tab). */
|
|
8
|
+
icon?: React.ReactNode;
|
|
9
|
+
/** Marcador numérico à direita (ex.: contagem de itens da tab). */
|
|
10
|
+
count?: number;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface TabsProps {
|
|
14
|
+
items: TabsItem[];
|
|
15
|
+
activeId: string;
|
|
16
|
+
onSelect?: (id: string) => void;
|
|
17
|
+
/** Centra as tabs no contentor (headers de popup/editor). */
|
|
18
|
+
centered?: boolean;
|
|
19
|
+
/** Desabilita todas as tabs. */
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
className?: string;
|
|
22
|
+
ariaLabel?: string;
|
|
23
|
+
}
|
|
24
|
+
export default function Tabs({ items, activeId, onSelect, centered, disabled, className, ariaLabel }: TabsProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Tabs/Tabs/Tabs.tsx"],"names":[],"mappings":"AAEA,OAAO,KAA4B,MAAM,OAAO,CAAC;AAGjD,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX;uEACmE;IACnE,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,0DAA0D;IAC1D,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,mEAAmE;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gCAAgC;IAChC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAc,EAAE,SAAS,EAAE,EAAE,SAAS,2CAqDnH"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from 'react';
|
|
4
|
+
import styles from './Tabs.module.css';
|
|
5
|
+
// Barra de tabs principais — border-bottom azul no activo e scroll-x
|
|
6
|
+
// quando não cabem; o activo nunca fica cortado nem encostado à borda
|
|
7
|
+
// (o scrollIntoView ignora o padding, por isso o cálculo é manual).
|
|
8
|
+
export default function Tabs({ items, activeId, onSelect, centered, disabled, className = '', ariaLabel }) {
|
|
9
|
+
const containerRef = useRef(null);
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
const container = containerRef.current;
|
|
12
|
+
const activeEl = container === null || container === void 0 ? void 0 : container.querySelector(`.${styles.activeTab}`);
|
|
13
|
+
if (!container || !activeEl)
|
|
14
|
+
return;
|
|
15
|
+
const cs = getComputedStyle(container);
|
|
16
|
+
const padL = parseFloat(cs.paddingLeft) || 0;
|
|
17
|
+
const padR = parseFloat(cs.paddingRight) || 0;
|
|
18
|
+
const elRect = activeEl.getBoundingClientRect();
|
|
19
|
+
const cRect = container.getBoundingClientRect();
|
|
20
|
+
const overRight = elRect.right + padR - cRect.right;
|
|
21
|
+
const overLeft = cRect.left + padL - elRect.left;
|
|
22
|
+
if (overRight > 0) {
|
|
23
|
+
container.scrollTo({ left: container.scrollLeft + overRight, behavior: 'smooth' });
|
|
24
|
+
}
|
|
25
|
+
else if (overLeft > 0) {
|
|
26
|
+
container.scrollTo({ left: container.scrollLeft - overLeft, behavior: 'smooth' });
|
|
27
|
+
}
|
|
28
|
+
}, [activeId]);
|
|
29
|
+
return (_jsx("div", { className: `${styles.tabsContainer} ${centered ? styles.tabsCentered : ''} ${className}`, ref: containerRef, role: "tablist", "aria-label": ariaLabel, children: items.map((tab) => {
|
|
30
|
+
const isActive = activeId === tab.id;
|
|
31
|
+
const tabDisabled = disabled || tab.disabled;
|
|
32
|
+
return (_jsxs("button", { type: "button", role: "tab", "aria-selected": isActive, onClick: () => !tabDisabled && (onSelect === null || onSelect === void 0 ? void 0 : onSelect(tab.id)), className: `${styles.tab} ${isActive ? styles.activeTab : ''} ${tabDisabled ? styles.disabledTab : ''}`, disabled: tabDisabled, children: [tab.icon && _jsx("span", { className: styles.tabIconWrap, children: tab.icon }), tab.label, tab.count !== undefined && tab.count > 0 && (_jsx("span", { className: `${styles.tabCount} ${isActive ? styles.activeTabCount : ''}`, children: tab.count }))] }, tab.id));
|
|
33
|
+
}) }));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=Tabs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tabs.js","sourceRoot":"","sources":["../../../../../../src/features/data-display/components/Tabs/Tabs/Tabs.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
.tabsContainer {
|
|
2
|
+
display: flex;
|
|
3
|
+
padding: 0 var(--spacing-md);
|
|
4
|
+
overflow-x: auto;
|
|
5
|
+
scrollbar-width: none;
|
|
6
|
+
-ms-overflow-style: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.tabsContainer::-webkit-scrollbar {
|
|
10
|
+
display: none;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/* Tabs centradas — headers de popup/editor (o default é alinhado à
|
|
14
|
+
esquerda, como nas listas). */
|
|
15
|
+
.tabsCentered {
|
|
16
|
+
justify-content: center;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.tab {
|
|
20
|
+
display: inline-flex;
|
|
21
|
+
align-items: center;
|
|
22
|
+
/* Ícone colado ao texto — sem respiro grande entre eles. */
|
|
23
|
+
gap: 5px;
|
|
24
|
+
padding: 12px var(--spacing-md);
|
|
25
|
+
border: none;
|
|
26
|
+
border-bottom: 3px solid transparent;
|
|
27
|
+
background: none;
|
|
28
|
+
color: var(--text-secondary);
|
|
29
|
+
font-size: 0.9rem;
|
|
30
|
+
font-weight: 600;
|
|
31
|
+
cursor: pointer;
|
|
32
|
+
white-space: nowrap;
|
|
33
|
+
transition: all 0.2s ease;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/* Ícone à esquerda do texto da tab — herda a cor do estado. */
|
|
37
|
+
.tabIconWrap {
|
|
38
|
+
display: inline-flex;
|
|
39
|
+
align-items: center;
|
|
40
|
+
flex-shrink: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
.tab:hover {
|
|
44
|
+
color: var(--text-primary);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.activeTab {
|
|
48
|
+
color: var(--color-primary-light);
|
|
49
|
+
border-bottom: 3px solid var(--color-primary-light);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.tabCount {
|
|
53
|
+
background-color: var(--color-gray-200);
|
|
54
|
+
color: var(--text-secondary);
|
|
55
|
+
border-radius: 12px;
|
|
56
|
+
padding: 2px 8px;
|
|
57
|
+
font-size: 12px;
|
|
58
|
+
font-weight: 500;
|
|
59
|
+
/* O gap do flex já dá respiro — o count fica a +3px do texto. */
|
|
60
|
+
margin-left: 3px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.activeTabCount {
|
|
64
|
+
background-color: var(--color-primary-light);
|
|
65
|
+
color: var(--color-white);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* Disabled — cinza atenuado, sem hover nem clique. */
|
|
69
|
+
.disabledTab {
|
|
70
|
+
background-color: transparent;
|
|
71
|
+
color: var(--text-tertiary);
|
|
72
|
+
opacity: 0.45;
|
|
73
|
+
cursor: not-allowed;
|
|
74
|
+
pointer-events: none;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.disabledTab:hover {
|
|
78
|
+
background-color: transparent;
|
|
79
|
+
color: var(--text-tertiary);
|
|
80
|
+
opacity: 0.45;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.disabledTab .tabIconWrap {
|
|
84
|
+
color: var(--text-tertiary);
|
|
85
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export interface CheckboxProps {
|
|
3
|
+
checked: boolean;
|
|
4
|
+
onChange: (checked: boolean) => void;
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
/** Círculo — o estilo de selecção de listas (tipo avatar-picker). */
|
|
8
|
+
circle?: boolean;
|
|
9
|
+
/** Estado parcial (subconjunto seleccionado) — mostra o traço. */
|
|
10
|
+
indeterminate?: boolean;
|
|
11
|
+
ariaLabel?: string;
|
|
12
|
+
id?: string;
|
|
13
|
+
name?: string;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function Checkbox({ checked, onChange, label, disabled, circle, indeterminate, ariaLabel, id, name, className, }: CheckboxProps): import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=Checkbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/Checkbox.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,kEAAkE;IAClE,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAgB,EAChB,MAAc,EACd,aAAqB,EACrB,SAAS,EACT,EAAE,EACF,IAAI,EACJ,SAAc,GACf,EAAE,aAAa,2CAqCf"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useEffect } from 'react';
|
|
4
|
+
import styles from './Checkbox.module.css';
|
|
5
|
+
// Checkbox partilhado — caixa 20×20 com check; `circle` para a versão
|
|
6
|
+
// redonda e `indeterminate` para selecção parcial.
|
|
7
|
+
export function Checkbox({ checked, onChange, label, disabled = false, circle = false, indeterminate = false, ariaLabel, id, name, className = '', }) {
|
|
8
|
+
const inputRef = useRef(null);
|
|
9
|
+
// indeterminate é property, não atributo — aplica-se por ref.
|
|
10
|
+
useEffect(() => {
|
|
11
|
+
if (inputRef.current)
|
|
12
|
+
inputRef.current.indeterminate = indeterminate;
|
|
13
|
+
}, [indeterminate]);
|
|
14
|
+
return (_jsxs("label", { className: `${styles.wrapper} ${disabled ? styles.disabled : ''} ${indeterminate ? styles.partial : ''} ${className}`, children: [_jsxs("span", { className: `${styles.box} ${circle ? styles.circle : ''}`, children: [_jsx("input", { type: "checkbox", ref: inputRef, id: id, name: name, checked: checked, disabled: disabled, onChange: (e) => onChange(e.target.checked), "aria-label": ariaLabel, className: styles.input }), indeterminate && !checked ? (_jsx("svg", { className: styles.check, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M3.5 8H12.5", stroke: "white", strokeWidth: "2", strokeLinecap: "round" }) })) : (_jsx("svg", { className: styles.check, viewBox: "0 0 16 16", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M3.5 8.5L6.5 11.5L12.5 4.5", stroke: "white", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }))] }), label && _jsx("span", { className: styles.label, children: label })] }));
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=Checkbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Checkbox.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/Checkbox.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAEb,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,MAAM,MAAM,uBAAuB,CAAC;AAiB3C,sEAAsE;AACtE,mDAAmD;AACnD,MAAM,UAAU,QAAQ,CAAC,EACvB,OAAO,EACP,QAAQ,EACR,KAAK,EACL,QAAQ,GAAG,KAAK,EAChB,MAAM,GAAG,KAAK,EACd,aAAa,GAAG,KAAK,EACrB,SAAS,EACT,EAAE,EACF,IAAI,EACJ,SAAS,GAAG,EAAE,GACA;IACd,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC,CAAC;IAEhD,8DAA8D;IAC9D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,QAAQ,CAAC,OAAO;YAAE,QAAQ,CAAC,OAAO,CAAC,aAAa,GAAG,aAAa,CAAC;IACvE,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,OAAO,CACL,iBACE,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,aAErH,gBAAM,SAAS,EAAE,GAAG,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,aAC7D,gBACE,IAAI,EAAC,UAAU,EACf,GAAG,EAAE,QAAQ,EACb,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,gBAC/B,SAAS,EACrB,SAAS,EAAE,MAAM,CAAC,KAAK,GACvB,EACD,aAAa,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAC3B,cAAK,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,YAC9E,eAAM,CAAC,EAAC,aAAa,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,GAAG,GACzE,CACP,CAAC,CAAC,CAAC,CACF,cAAK,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,iBAAa,MAAM,YAC9E,eAAM,CAAC,EAAC,4BAA4B,EAAC,MAAM,EAAC,OAAO,EAAC,WAAW,EAAC,GAAG,EAAC,aAAa,EAAC,OAAO,EAAC,cAAc,EAAC,OAAO,GAAG,GAC/G,CACP,IACI,EACN,KAAK,IAAI,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAQ,IACjD,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 8px;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
user-select: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wrapper.disabled {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
opacity: 0.5;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.box {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: 20px;
|
|
17
|
+
height: 20px;
|
|
18
|
+
border-radius: 5px;
|
|
19
|
+
border: 2px solid var(--bg-interactive);
|
|
20
|
+
background: transparent;
|
|
21
|
+
transition: background 0.15s ease, border-color 0.15s ease;
|
|
22
|
+
flex-shrink: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/* Variante circular — o check de selecção de listas. */
|
|
26
|
+
.box.circle {
|
|
27
|
+
border-radius: 50%;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.input {
|
|
31
|
+
position: absolute;
|
|
32
|
+
inset: 0;
|
|
33
|
+
margin: 0;
|
|
34
|
+
opacity: 0;
|
|
35
|
+
cursor: inherit;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.check {
|
|
39
|
+
position: absolute;
|
|
40
|
+
inset: 0;
|
|
41
|
+
width: 100%;
|
|
42
|
+
height: 100%;
|
|
43
|
+
opacity: 0;
|
|
44
|
+
transform: scale(0.6);
|
|
45
|
+
transition: opacity 0.15s ease, transform 0.15s ease;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.input:checked ~ .check,
|
|
49
|
+
.wrapper.partial .check {
|
|
50
|
+
opacity: 1;
|
|
51
|
+
transform: scale(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.box:has(.input:checked),
|
|
55
|
+
.wrapper.partial .box {
|
|
56
|
+
background: var(--bg-interactive);
|
|
57
|
+
border-color: var(--bg-interactive);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
.input:focus-visible ~ .check {
|
|
61
|
+
outline: 2px solid var(--bg-interactive);
|
|
62
|
+
outline-offset: 2px;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.label {
|
|
66
|
+
font-size: 0.875rem;
|
|
67
|
+
color: var(--text-primary);
|
|
68
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export interface FormLabelProps {
|
|
3
|
+
htmlFor: string;
|
|
4
|
+
children: React.ReactNode;
|
|
5
|
+
required?: boolean;
|
|
6
|
+
/** Texto do marcador opcional — i18n do consumidor (ex.:
|
|
7
|
+
* '(Opcional)', '(optional)'); renderiza à direita do label. */
|
|
8
|
+
optionalLabel?: React.ReactNode;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export default function FormLabel({ htmlFor, children, required, optionalLabel, className, }: FormLabelProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=FormLabel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormLabel.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/FormLabel.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;qEACiE;IACjE,aAAa,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAgB,EAChB,aAAa,EACb,SAAc,GACf,EAAE,cAAc,2CAUhB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Asterisk } from 'lucide-react';
|
|
4
|
+
import styles from './FormLabel.module.css';
|
|
5
|
+
// Label de campo de formulário — texto 0.95rem/500; obrigatório leva
|
|
6
|
+
// o asterisco vermelho, opcional o marcador do consumidor.
|
|
7
|
+
export default function FormLabel({ htmlFor, children, required = false, optionalLabel, className = '', }) {
|
|
8
|
+
return (_jsxs("label", { htmlFor: htmlFor, className: `${styles.label} ${className}`, children: [_jsx("span", { className: styles.text, children: children }), required && _jsx(Asterisk, { size: 14, className: styles.requiredIcon }), !required && optionalLabel != null && (_jsx("span", { className: styles.optionalText, children: optionalLabel }))] }));
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=FormLabel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormLabel.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/FormLabel.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,MAAM,MAAM,wBAAwB,CAAC;AAY5C,qEAAqE;AACrE,2DAA2D;AAC3D,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,EAChC,OAAO,EACP,QAAQ,EACR,QAAQ,GAAG,KAAK,EAChB,aAAa,EACb,SAAS,GAAG,EAAE,GACC;IACf,OAAO,CACL,iBAAO,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,EAAE,aAChE,eAAM,SAAS,EAAE,MAAM,CAAC,IAAI,YAAG,QAAQ,GAAQ,EAC9C,QAAQ,IAAI,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,GAAI,EAClE,CAAC,QAAQ,IAAI,aAAa,IAAI,IAAI,IAAI,CACrC,eAAM,SAAS,EAAE,MAAM,CAAC,YAAY,YAAG,aAAa,GAAQ,CAC7D,IACK,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
.label {
|
|
2
|
+
display: flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: var(--spacing-xs);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.text {
|
|
8
|
+
font-size: 0.95rem;
|
|
9
|
+
font-weight: 500;
|
|
10
|
+
color: var(--text-primary);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.requiredIcon {
|
|
14
|
+
color: var(--color-error);
|
|
15
|
+
font-weight: 600;
|
|
16
|
+
flex-shrink: 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.optionalText {
|
|
20
|
+
font-size: 0.9rem;
|
|
21
|
+
color: var(--text-tertiary);
|
|
22
|
+
font-weight: 400;
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
export interface RadioButtonProps {
|
|
3
|
+
checked: boolean;
|
|
4
|
+
onChange: () => void;
|
|
5
|
+
label?: React.ReactNode;
|
|
6
|
+
name?: string;
|
|
7
|
+
value?: string;
|
|
8
|
+
id?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function RadioButton({ checked, onChange, label, name, value, id, disabled, className, }: RadioButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=RadioButton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioButton.d.ts","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/RadioButton.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,KAAK,EACL,EAAE,EACF,QAAgB,EAChB,SAAc,GACf,EAAE,gBAAgB,2CAmBlB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import styles from './RadioButton.module.css';
|
|
4
|
+
// Radio partilhado — o anel exterior é sempre azul; o que muda é só a
|
|
5
|
+
// bolinha interior que nasce quando marcado.
|
|
6
|
+
export function RadioButton({ checked, onChange, label, name, value, id, disabled = false, className = '', }) {
|
|
7
|
+
return (_jsxs("label", { className: `${styles.wrapper} ${disabled ? styles.disabled : ''} ${className}`, children: [_jsxs("span", { className: styles.circle, children: [_jsx("input", { type: "radio", id: id, name: name, value: value, checked: checked, disabled: disabled, onChange: onChange, className: styles.input }), _jsx("span", { className: styles.dot })] }), label && _jsx("span", { className: styles.label, children: label })] }));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=RadioButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioButton.js","sourceRoot":"","sources":["../../../../../src/features/inputs/components/Inputs/RadioButton.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,MAAM,MAAM,0BAA0B,CAAC;AAa9C,sEAAsE;AACtE,6CAA6C;AAC7C,MAAM,UAAU,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,KAAK,EACL,EAAE,EACF,QAAQ,GAAG,KAAK,EAChB,SAAS,GAAG,EAAE,GACG;IACjB,OAAO,CACL,iBAAO,SAAS,EAAE,GAAG,MAAM,CAAC,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,SAAS,EAAE,aACnF,gBAAM,SAAS,EAAE,MAAM,CAAC,MAAM,aAC5B,gBACE,IAAI,EAAC,OAAO,EACZ,EAAE,EAAE,EAAE,EACN,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE,MAAM,CAAC,KAAK,GACvB,EACF,eAAM,SAAS,EAAE,MAAM,CAAC,GAAG,GAAI,IAC1B,EACN,KAAK,IAAI,eAAM,SAAS,EAAE,MAAM,CAAC,KAAK,YAAG,KAAK,GAAQ,IACjD,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
.wrapper {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
align-items: center;
|
|
4
|
+
gap: 8px;
|
|
5
|
+
cursor: pointer;
|
|
6
|
+
user-select: none;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.wrapper.disabled {
|
|
10
|
+
cursor: not-allowed;
|
|
11
|
+
opacity: 0.5;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.circle {
|
|
15
|
+
position: relative;
|
|
16
|
+
width: 20px;
|
|
17
|
+
height: 20px;
|
|
18
|
+
border-radius: 50%;
|
|
19
|
+
background: transparent;
|
|
20
|
+
/* O anel exterior é SEMPRE azul, com ou sem selecção — o que muda
|
|
21
|
+
é só o interior (bolinha azul nasce quando marcado). */
|
|
22
|
+
border: 2px solid var(--bg-interactive);
|
|
23
|
+
transition: border-color 0.15s ease;
|
|
24
|
+
flex-shrink: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.input {
|
|
28
|
+
position: absolute;
|
|
29
|
+
inset: 0;
|
|
30
|
+
margin: 0;
|
|
31
|
+
opacity: 0;
|
|
32
|
+
cursor: inherit;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/* Dot — a bolinha azul cheia do estado seleccionado. 10px dentro do
|
|
36
|
+
anel de 20px (border 2px) deixa o espaço branco que separa os dois
|
|
37
|
+
— o padrão nativo. */
|
|
38
|
+
.dot {
|
|
39
|
+
position: absolute;
|
|
40
|
+
top: 50%;
|
|
41
|
+
left: 50%;
|
|
42
|
+
width: 10px;
|
|
43
|
+
height: 10px;
|
|
44
|
+
border-radius: 50%;
|
|
45
|
+
background: var(--bg-interactive);
|
|
46
|
+
transform: translate(-50%, -50%) scale(0);
|
|
47
|
+
transition: transform 0.15s ease;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.input:checked ~ .dot {
|
|
51
|
+
transform: translate(-50%, -50%) scale(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.circle:has(.input:checked) {
|
|
55
|
+
border-color: var(--bg-interactive);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.input:focus-visible ~ .dot {
|
|
59
|
+
outline: 2px solid var(--bg-interactive);
|
|
60
|
+
outline-offset: 2px;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.label {
|
|
64
|
+
font-size: 0.875rem;
|
|
65
|
+
color: var(--text-primary);
|
|
66
|
+
}
|