@clicoh/orion-library 1.1.0-beta.7 → 1.1.0-beta.8
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/assets/css/base.css +18 -0
- package/dist/components/01-atoms/Badge/Badge.d.ts +14 -4
- package/dist/components/01-atoms/Badge/Badge.d.ts.map +1 -1
- package/dist/components/01-atoms/Badge/Badge.jsx +34 -4
- package/dist/components/01-atoms/Badge/Badge.jsx.map +1 -1
- package/dist/components/01-atoms/CountryFlag/CountryFlag.d.ts +30 -0
- package/dist/components/01-atoms/CountryFlag/CountryFlag.d.ts.map +1 -0
- package/dist/components/01-atoms/CountryFlag/CountryFlag.jsx +105 -0
- package/dist/components/01-atoms/CountryFlag/CountryFlag.jsx.map +1 -0
- package/dist/components/01-atoms/CountryFlag/index.d.ts +3 -0
- package/dist/components/01-atoms/CountryFlag/index.d.ts.map +1 -0
- package/dist/components/01-atoms/CountryFlag/index.js +2 -0
- package/dist/components/01-atoms/CountryFlag/index.js.map +1 -0
- package/dist/components/01-atoms/Input/Input.d.ts +3 -1
- package/dist/components/01-atoms/Input/Input.d.ts.map +1 -1
- package/dist/components/01-atoms/Input/Input.jsx +5 -2
- package/dist/components/01-atoms/Input/Input.jsx.map +1 -1
- package/dist/components/01-atoms/Input/utils/border.d.ts +6 -1
- package/dist/components/01-atoms/Input/utils/border.d.ts.map +1 -1
- package/dist/components/01-atoms/Input/utils/border.js +13 -3
- package/dist/components/01-atoms/Input/utils/border.js.map +1 -1
- package/dist/components/01-atoms/MultiSelect/MultiSelect.d.ts +3 -1
- package/dist/components/01-atoms/MultiSelect/MultiSelect.d.ts.map +1 -1
- package/dist/components/01-atoms/MultiSelect/MultiSelect.jsx +17 -5
- package/dist/components/01-atoms/MultiSelect/MultiSelect.jsx.map +1 -1
- package/dist/components/01-atoms/Paragraph/Paragraph.d.ts +14 -4
- package/dist/components/01-atoms/Paragraph/Paragraph.d.ts.map +1 -1
- package/dist/components/01-atoms/Paragraph/Paragraph.jsx +30 -8
- package/dist/components/01-atoms/Paragraph/Paragraph.jsx.map +1 -1
- package/dist/components/01-atoms/Select/Select.d.ts +3 -1
- package/dist/components/01-atoms/Select/Select.d.ts.map +1 -1
- package/dist/components/01-atoms/Select/Select.jsx +10 -4
- package/dist/components/01-atoms/Select/Select.jsx.map +1 -1
- package/dist/components/01-atoms/index.d.ts +1 -0
- package/dist/components/01-atoms/index.d.ts.map +1 -1
- package/dist/components/01-atoms/index.js +1 -0
- package/dist/components/01-atoms/index.js.map +1 -1
- package/dist/components/02-molecules/Autocomplete/Autocomplete.d.ts +3 -1
- package/dist/components/02-molecules/Autocomplete/Autocomplete.d.ts.map +1 -1
- package/dist/components/02-molecules/Autocomplete/Autocomplete.jsx +3 -2
- package/dist/components/02-molecules/Autocomplete/Autocomplete.jsx.map +1 -1
- package/dist/components/02-molecules/BellNotifications/index.d.ts +1 -1
- package/dist/components/02-molecules/BellNotifications/index.d.ts.map +1 -1
- package/dist/components/02-molecules/Filter/Filter.d.ts +13 -50
- package/dist/components/02-molecules/Filter/Filter.d.ts.map +1 -1
- package/dist/components/02-molecules/Filter/Filter.jsx +156 -165
- package/dist/components/02-molecules/Filter/Filter.jsx.map +1 -1
- package/dist/components/02-molecules/Filter/index.d.ts +2 -0
- package/dist/components/02-molecules/Filter/index.d.ts.map +1 -1
- package/dist/components/02-molecules/Filter/index.js +2 -0
- package/dist/components/02-molecules/Filter/index.js.map +1 -1
- package/dist/components/02-molecules/Filter/types.d.ts +59 -0
- package/dist/components/02-molecules/Filter/types.d.ts.map +1 -0
- package/dist/components/02-molecules/Filter/types.js +2 -0
- package/dist/components/02-molecules/Filter/types.js.map +1 -0
- package/dist/components/02-molecules/Filter/utils/getFilterChips.d.ts +23 -0
- package/dist/components/02-molecules/Filter/utils/getFilterChips.d.ts.map +1 -0
- package/dist/components/02-molecules/Filter/utils/getFilterChips.js +47 -0
- package/dist/components/02-molecules/Filter/utils/getFilterChips.js.map +1 -0
- package/dist/components/02-molecules/FilterChips/FilterChips.d.ts +44 -0
- package/dist/components/02-molecules/FilterChips/FilterChips.d.ts.map +1 -0
- package/dist/components/02-molecules/FilterChips/FilterChips.jsx +60 -0
- package/dist/components/02-molecules/FilterChips/FilterChips.jsx.map +1 -0
- package/dist/components/02-molecules/FilterChips/index.d.ts +2 -0
- package/dist/components/02-molecules/FilterChips/index.d.ts.map +1 -0
- package/dist/components/02-molecules/FilterChips/index.js +2 -0
- package/dist/components/02-molecules/FilterChips/index.js.map +1 -0
- package/dist/components/02-molecules/ImageViewer/ImageViewer.d.ts +60 -0
- package/dist/components/02-molecules/ImageViewer/ImageViewer.d.ts.map +1 -0
- package/dist/components/02-molecules/ImageViewer/ImageViewer.jsx +144 -0
- package/dist/components/02-molecules/ImageViewer/ImageViewer.jsx.map +1 -0
- package/dist/components/02-molecules/ImageViewer/index.d.ts +2 -0
- package/dist/components/02-molecules/ImageViewer/index.d.ts.map +1 -0
- package/dist/components/02-molecules/ImageViewer/index.js +2 -0
- package/dist/components/02-molecules/ImageViewer/index.js.map +1 -0
- package/dist/components/02-molecules/SideNav/SideNav.d.ts +58 -0
- package/dist/components/02-molecules/SideNav/SideNav.d.ts.map +1 -0
- package/dist/components/02-molecules/SideNav/SideNav.jsx +53 -0
- package/dist/components/02-molecules/SideNav/SideNav.jsx.map +1 -0
- package/dist/components/02-molecules/SideNav/SideNavItem.d.ts +36 -0
- package/dist/components/02-molecules/SideNav/SideNavItem.d.ts.map +1 -0
- package/dist/components/02-molecules/SideNav/SideNavItem.jsx +38 -0
- package/dist/components/02-molecules/SideNav/SideNavItem.jsx.map +1 -0
- package/dist/components/02-molecules/SideNav/index.d.ts +3 -0
- package/dist/components/02-molecules/SideNav/index.d.ts.map +1 -0
- package/dist/components/02-molecules/SideNav/index.js +3 -0
- package/dist/components/02-molecules/SideNav/index.js.map +1 -0
- package/dist/components/02-molecules/Tab/TabItem.d.ts +4 -1
- package/dist/components/02-molecules/Tab/TabItem.d.ts.map +1 -1
- package/dist/components/02-molecules/Tab/TabItem.jsx +9 -2
- package/dist/components/02-molecules/Tab/TabItem.jsx.map +1 -1
- package/dist/components/02-molecules/Tab/TabList.d.ts +12 -2
- package/dist/components/02-molecules/Tab/TabList.d.ts.map +1 -1
- package/dist/components/02-molecules/Tab/TabList.jsx +40 -9
- package/dist/components/02-molecules/Tab/TabList.jsx.map +1 -1
- package/dist/components/02-molecules/Table/Table.d.ts.map +1 -1
- package/dist/components/02-molecules/Table/Table.jsx +6 -3
- package/dist/components/02-molecules/Table/Table.jsx.map +1 -1
- package/dist/components/02-molecules/index.d.ts +3 -0
- package/dist/components/02-molecules/index.d.ts.map +1 -1
- package/dist/components/02-molecules/index.js +3 -0
- package/dist/components/02-molecules/index.js.map +1 -1
- package/dist/components/03-organisms/AsideFilters/AsideFilters.jsx +1 -1
- package/dist/components/03-organisms/AsideFilters/AsideFilters.jsx.map +1 -1
- package/dist/components/03-organisms/DataTable/DataTable.d.ts +10 -1
- package/dist/components/03-organisms/DataTable/DataTable.d.ts.map +1 -1
- package/dist/components/03-organisms/DataTable/DataTable.jsx +16 -3
- package/dist/components/03-organisms/DataTable/DataTable.jsx.map +1 -1
- package/dist/components/03-organisms/Header/HeaderActions.d.ts.map +1 -1
- package/dist/components/03-organisms/Header/HeaderActions.jsx +1 -1
- package/dist/components/03-organisms/Header/HeaderActions.jsx.map +1 -1
- package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.d.ts +3 -1
- package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.d.ts.map +1 -1
- package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.jsx +3 -1
- package/dist/components/04-templates/SideFilterTemplate/SideFilterTemplate.jsx.map +1 -1
- package/package.json +1 -1
- package/tailwind.config.ts +21 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
import { type OptionType } from '../../01-atoms';
|
|
3
|
+
import type { TFilterInputs, TFilterValues } from '../Filter/types';
|
|
4
|
+
type FilterChipsProps = {
|
|
5
|
+
inputs: TFilterInputs;
|
|
6
|
+
values: Record<string, TFilterValues>;
|
|
7
|
+
onRemove: (key: string) => void;
|
|
8
|
+
onClearAll?: () => void;
|
|
9
|
+
clearAllText?: string;
|
|
10
|
+
removeFilterLabel?: (filterLabel: string) => string;
|
|
11
|
+
extraOptions?: Record<string, OptionType[]>;
|
|
12
|
+
} & Omit<HTMLAttributes<HTMLUListElement>, 'children'>;
|
|
13
|
+
/**
|
|
14
|
+
* FilterChips component for rendering the applied filters as removable chips.
|
|
15
|
+
*
|
|
16
|
+
* Resolves every chip label against the same configuration the Filter uses, so
|
|
17
|
+
* the chips read the same inside the panel and outside of it. Renders nothing
|
|
18
|
+
* while no filter is applied.
|
|
19
|
+
*
|
|
20
|
+
* @component
|
|
21
|
+
* @example
|
|
22
|
+
* <FilterChips
|
|
23
|
+
* inputs={config}
|
|
24
|
+
* values={{ country: [{ value: 1, label: 'México' }] }}
|
|
25
|
+
* onRemove={(key) => removeFilter(key)}
|
|
26
|
+
* onClearAll={() => resetFilters()}
|
|
27
|
+
* clearAllText="Limpiar todos"
|
|
28
|
+
* />
|
|
29
|
+
*
|
|
30
|
+
* @param {Object} props - The properties of the FilterChips component.
|
|
31
|
+
* @param {TFilterInputs} props.inputs - Filter configuration used to resolve the labels.
|
|
32
|
+
* @param {Object} props.values - Applied filter values, keyed by filter key.
|
|
33
|
+
* @param {Function} props.onRemove - Callback triggered with the key of the removed filter.
|
|
34
|
+
* @param {Function} [props.onClearAll] - Callback that clears every filter. The action is hidden when omitted.
|
|
35
|
+
* @param {string} [props.clearAllText] - Text of the clear all action.
|
|
36
|
+
* @param {Function} [props.removeFilterLabel] - Builds the accessible label of each remove button.
|
|
37
|
+
* @param {Object} [props.extraOptions] - Asynchronously loaded options, keyed by filter key.
|
|
38
|
+
* @param {HTMLAttributes<HTMLUListElement>} [props.restProps] - Additional attributes for the list element.
|
|
39
|
+
*
|
|
40
|
+
* @returns {ReactNode} The rendered FilterChips component.
|
|
41
|
+
*/
|
|
42
|
+
export declare function FilterChips({ inputs, values, onRemove, onClearAll, clearAllText, removeFilterLabel, extraOptions, ...restProps }: FilterChipsProps): ReactNode;
|
|
43
|
+
export {};
|
|
44
|
+
//# sourceMappingURL=FilterChips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/FilterChips/FilterChips.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAG5D,OAAO,EAAQ,KAAK,UAAU,EAAa,MAAM,gBAAgB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGpE,KAAK,gBAAgB,GAAG;IACtB,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACtC,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iBAAiB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,MAAM,CAAC;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;CAC7C,GAAG,IAAI,CAAC,cAAc,CAAC,gBAAgB,CAAC,EAAE,UAAU,CAAC,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,GAAG,SAAS,EACb,EAAE,gBAAgB,GAAG,SAAS,CA4C9B"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { MdClose } from 'react-icons/md';
|
|
4
|
+
import { Each, Show } from '../../00-base';
|
|
5
|
+
import { List, Paragraph } from '../../01-atoms';
|
|
6
|
+
import { getFilterChips } from '../Filter/utils/getFilterChips';
|
|
7
|
+
/**
|
|
8
|
+
* FilterChips component for rendering the applied filters as removable chips.
|
|
9
|
+
*
|
|
10
|
+
* Resolves every chip label against the same configuration the Filter uses, so
|
|
11
|
+
* the chips read the same inside the panel and outside of it. Renders nothing
|
|
12
|
+
* while no filter is applied.
|
|
13
|
+
*
|
|
14
|
+
* @component
|
|
15
|
+
* @example
|
|
16
|
+
* <FilterChips
|
|
17
|
+
* inputs={config}
|
|
18
|
+
* values={{ country: [{ value: 1, label: 'México' }] }}
|
|
19
|
+
* onRemove={(key) => removeFilter(key)}
|
|
20
|
+
* onClearAll={() => resetFilters()}
|
|
21
|
+
* clearAllText="Limpiar todos"
|
|
22
|
+
* />
|
|
23
|
+
*
|
|
24
|
+
* @param {Object} props - The properties of the FilterChips component.
|
|
25
|
+
* @param {TFilterInputs} props.inputs - Filter configuration used to resolve the labels.
|
|
26
|
+
* @param {Object} props.values - Applied filter values, keyed by filter key.
|
|
27
|
+
* @param {Function} props.onRemove - Callback triggered with the key of the removed filter.
|
|
28
|
+
* @param {Function} [props.onClearAll] - Callback that clears every filter. The action is hidden when omitted.
|
|
29
|
+
* @param {string} [props.clearAllText] - Text of the clear all action.
|
|
30
|
+
* @param {Function} [props.removeFilterLabel] - Builds the accessible label of each remove button.
|
|
31
|
+
* @param {Object} [props.extraOptions] - Asynchronously loaded options, keyed by filter key.
|
|
32
|
+
* @param {HTMLAttributes<HTMLUListElement>} [props.restProps] - Additional attributes for the list element.
|
|
33
|
+
*
|
|
34
|
+
* @returns {ReactNode} The rendered FilterChips component.
|
|
35
|
+
*/
|
|
36
|
+
export function FilterChips({ inputs, values, onRemove, onClearAll, clearAllText, removeFilterLabel, extraOptions, ...restProps }) {
|
|
37
|
+
const chips = getFilterChips({ inputs, values, extraOptions });
|
|
38
|
+
if (!chips.length)
|
|
39
|
+
return null;
|
|
40
|
+
return (<List {...restProps} orientation="horizontal" className={clsx('flex-wrap gap-2', restProps.className)}>
|
|
41
|
+
<Each of={chips} render={({ key, label, text }) => (<li key={key}>
|
|
42
|
+
<div className="bg-gray-5 dark:bg-gray-1 inline-flex items-center rounded-full px-4 py-2 dark:text-white">
|
|
43
|
+
<Paragraph size="chips">{text}</Paragraph>
|
|
44
|
+
<button type="button" aria-label={removeFilterLabel?.(label) ?? label} onClick={() => onRemove(key)} className="bg-error ml-1.5 inline-flex h-4 w-4 cursor-pointer items-center justify-center rounded-full p-0.5 text-white">
|
|
45
|
+
<MdClose aria-hidden="true"/>
|
|
46
|
+
</button>
|
|
47
|
+
</div>
|
|
48
|
+
</li>)}/>
|
|
49
|
+
<Show>
|
|
50
|
+
<Show.When isTrue={Boolean(onClearAll && clearAllText)}>
|
|
51
|
+
<li>
|
|
52
|
+
<button type="button" onClick={onClearAll} className="hover:text-gray-1 dark:hover:text-gray-2 cursor-pointer text-sm underline underline-offset-2 dark:text-white">
|
|
53
|
+
{clearAllText}
|
|
54
|
+
</button>
|
|
55
|
+
</li>
|
|
56
|
+
</Show.When>
|
|
57
|
+
</Show>
|
|
58
|
+
</List>);
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=FilterChips.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FilterChips.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/FilterChips/FilterChips.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAmB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElE,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAYhE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,MAAM,EACN,MAAM,EACN,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,YAAY,EACZ,GAAG,SAAS,EACK;IACjB,MAAM,KAAK,GAAG,cAAc,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAE/D,IAAI,CAAC,KAAK,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE/B,OAAO,CACL,CAAC,IAAI,CACH,IAAI,SAAS,CAAC,CACd,WAAW,CAAC,YAAY,CACxB,SAAS,CAAC,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAExD;MAAA,CAAC,IAAI,CACH,EAAE,CAAC,CAAC,KAAK,CAAC,CACV,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAChC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CACX;YAAA,CAAC,GAAG,CAAC,SAAS,CAAC,0FAA0F,CACvG;cAAA,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,SAAS,CACzC;cAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAChD,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAC7B,SAAS,CAAC,8GAA8G,CAExH;gBAAA,CAAC,OAAO,CAAC,WAAW,CAAC,MAAM,EAC7B;cAAA,EAAE,MAAM,CACV;YAAA,EAAE,GAAG,CACP;UAAA,EAAE,EAAE,CAAC,CACN,CAAC,EAEJ;MAAA,CAAC,IAAI,CACH;QAAA,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,UAAU,IAAI,YAAY,CAAC,CAAC,CACrD;UAAA,CAAC,EAAE,CACD;YAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,OAAO,CAAC,CAAC,UAAU,CAAC,CACpB,SAAS,CAAC,8GAA8G,CAExH;cAAA,CAAC,YAAY,CACf;YAAA,EAAE,MAAM,CACV;UAAA,EAAE,EAAE,CACN;QAAA,EAAE,IAAI,CAAC,IAAI,CACb;MAAA,EAAE,IAAI,CACR;IAAA,EAAE,IAAI,CAAC,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/FilterChips/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/02-molecules/FilterChips/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
export type TImageView = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
src: string;
|
|
6
|
+
alt: string;
|
|
7
|
+
};
|
|
8
|
+
export type TImageViewerLabels = {
|
|
9
|
+
zoomIn: string;
|
|
10
|
+
zoomOut: string;
|
|
11
|
+
rotate: string;
|
|
12
|
+
enterFullscreen: string;
|
|
13
|
+
exitFullscreen: string;
|
|
14
|
+
};
|
|
15
|
+
type ImageViewerProps = {
|
|
16
|
+
views: TImageView[];
|
|
17
|
+
labels: TImageViewerLabels;
|
|
18
|
+
title?: ReactNode;
|
|
19
|
+
emptyState?: ReactNode;
|
|
20
|
+
} & Omit<HTMLAttributes<HTMLElement>, 'children' | 'title'>;
|
|
21
|
+
/**
|
|
22
|
+
* ImageViewer component for inspecting one or more images of the same subject.
|
|
23
|
+
*
|
|
24
|
+
* Each view is a tab, so a subject photographed from several angles reads as one
|
|
25
|
+
* piece instead of a gallery. Zoom and rotation reset when the view changes: a
|
|
26
|
+
* transform that made sense for one angle rarely makes sense for the next.
|
|
27
|
+
*
|
|
28
|
+
* Renders `emptyState` while `views` is empty, and disables the toolbar with it,
|
|
29
|
+
* so the frame keeps its size instead of collapsing.
|
|
30
|
+
*
|
|
31
|
+
* @component
|
|
32
|
+
* @example
|
|
33
|
+
* <ImageViewer
|
|
34
|
+
* title="Identity document"
|
|
35
|
+
* views={[
|
|
36
|
+
* { id: 'front', label: 'Front', src: '/front.jpg', alt: 'Document front' },
|
|
37
|
+
* { id: 'back', label: 'Back', src: '/back.jpg', alt: 'Document back' },
|
|
38
|
+
* ]}
|
|
39
|
+
* labels={{
|
|
40
|
+
* zoomIn: 'Zoom in',
|
|
41
|
+
* zoomOut: 'Zoom out',
|
|
42
|
+
* rotate: 'Rotate',
|
|
43
|
+
* enterFullscreen: 'Full screen',
|
|
44
|
+
* exitFullscreen: 'Exit full screen',
|
|
45
|
+
* }}
|
|
46
|
+
* emptyState={<p>Nothing uploaded yet</p>}
|
|
47
|
+
* />
|
|
48
|
+
*
|
|
49
|
+
* @param {Object} props - The properties of the ImageViewer component.
|
|
50
|
+
* @param {TImageView[]} props.views - Images to display. More than one renders a tab per view.
|
|
51
|
+
* @param {TImageViewerLabels} props.labels - Accessible names of the toolbar actions.
|
|
52
|
+
* @param {ReactNode} [props.title] - Optional heading rendered on the left of the toolbar.
|
|
53
|
+
* @param {ReactNode} [props.emptyState] - Content rendered when there is no image.
|
|
54
|
+
* @param {HTMLAttributes<HTMLElement>} [props.restProps] - Additional attributes for the root element.
|
|
55
|
+
*
|
|
56
|
+
* @returns {ReactNode} The rendered ImageViewer component.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ImageViewer({ views, labels, title, emptyState, ...restProps }: ImageViewerProps): ReactNode;
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=ImageViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageViewer.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/ImageViewer/ImageViewer.tsx"],"names":[],"mappings":"AAGA,OAAO,EAIL,KAAK,cAAc,EACnB,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAaf,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,KAAK,gBAAgB,GAAG;IACtB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,kBAAkB,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,UAAU,CAAC,EAAE,SAAS,CAAC;CACxB,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC;AAW5D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,GAAG,SAAS,EACb,EAAE,gBAAgB,GAAG,SAAS,CA6K9B"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { useEffect, useId, useState, } from 'react';
|
|
4
|
+
import { createPortal } from 'react-dom';
|
|
5
|
+
import { MdFullscreen, MdFullscreenExit, MdRotateRight, MdZoomIn, MdZoomOut, } from 'react-icons/md';
|
|
6
|
+
import { Each, Show } from '../../00-base';
|
|
7
|
+
import { List, Paragraph } from '../../01-atoms';
|
|
8
|
+
import { TabItem } from '../Tab/TabItem';
|
|
9
|
+
const MIN_ZOOM = 1;
|
|
10
|
+
const MAX_ZOOM = 3;
|
|
11
|
+
const ZOOM_STEP = 0.5;
|
|
12
|
+
const QUARTER_TURN = 90;
|
|
13
|
+
const FULL_TURN = 360;
|
|
14
|
+
const TOOL_CLASSNAME = 'hover:bg-gray-5 focus-visible:ring-lavender disabled:text-gray-3 dark:disabled:text-gray-1 dark:hover:bg-gray-1 flex h-8 w-8 cursor-pointer items-center justify-center rounded-sm text-lg text-black focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:hover:bg-transparent dark:text-white';
|
|
15
|
+
/**
|
|
16
|
+
* ImageViewer component for inspecting one or more images of the same subject.
|
|
17
|
+
*
|
|
18
|
+
* Each view is a tab, so a subject photographed from several angles reads as one
|
|
19
|
+
* piece instead of a gallery. Zoom and rotation reset when the view changes: a
|
|
20
|
+
* transform that made sense for one angle rarely makes sense for the next.
|
|
21
|
+
*
|
|
22
|
+
* Renders `emptyState` while `views` is empty, and disables the toolbar with it,
|
|
23
|
+
* so the frame keeps its size instead of collapsing.
|
|
24
|
+
*
|
|
25
|
+
* @component
|
|
26
|
+
* @example
|
|
27
|
+
* <ImageViewer
|
|
28
|
+
* title="Identity document"
|
|
29
|
+
* views={[
|
|
30
|
+
* { id: 'front', label: 'Front', src: '/front.jpg', alt: 'Document front' },
|
|
31
|
+
* { id: 'back', label: 'Back', src: '/back.jpg', alt: 'Document back' },
|
|
32
|
+
* ]}
|
|
33
|
+
* labels={{
|
|
34
|
+
* zoomIn: 'Zoom in',
|
|
35
|
+
* zoomOut: 'Zoom out',
|
|
36
|
+
* rotate: 'Rotate',
|
|
37
|
+
* enterFullscreen: 'Full screen',
|
|
38
|
+
* exitFullscreen: 'Exit full screen',
|
|
39
|
+
* }}
|
|
40
|
+
* emptyState={<p>Nothing uploaded yet</p>}
|
|
41
|
+
* />
|
|
42
|
+
*
|
|
43
|
+
* @param {Object} props - The properties of the ImageViewer component.
|
|
44
|
+
* @param {TImageView[]} props.views - Images to display. More than one renders a tab per view.
|
|
45
|
+
* @param {TImageViewerLabels} props.labels - Accessible names of the toolbar actions.
|
|
46
|
+
* @param {ReactNode} [props.title] - Optional heading rendered on the left of the toolbar.
|
|
47
|
+
* @param {ReactNode} [props.emptyState] - Content rendered when there is no image.
|
|
48
|
+
* @param {HTMLAttributes<HTMLElement>} [props.restProps] - Additional attributes for the root element.
|
|
49
|
+
*
|
|
50
|
+
* @returns {ReactNode} The rendered ImageViewer component.
|
|
51
|
+
*/
|
|
52
|
+
export function ImageViewer({ views, labels, title, emptyState, ...restProps }) {
|
|
53
|
+
const [activeIndex, setActiveIndex] = useState(0);
|
|
54
|
+
const [zoom, setZoom] = useState(MIN_ZOOM);
|
|
55
|
+
const [rotation, setRotation] = useState(0);
|
|
56
|
+
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
57
|
+
const generatedId = useId();
|
|
58
|
+
/**
|
|
59
|
+
* Se sigue la firma de las vistas y no el arreglo: un consumidor que lo
|
|
60
|
+
* declare en linea entrega una referencia nueva en cada render y el visor se
|
|
61
|
+
* reiniciaria mientras el usuario lo esta usando.
|
|
62
|
+
*/
|
|
63
|
+
const viewsSignature = views.map(({ id }) => id).join('|');
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
setActiveIndex(0);
|
|
66
|
+
setZoom(MIN_ZOOM);
|
|
67
|
+
setRotation(0);
|
|
68
|
+
}, [viewsSignature]);
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
if (!isFullscreen)
|
|
71
|
+
return;
|
|
72
|
+
const handleKeyDown = (event) => {
|
|
73
|
+
if (event.key === 'Escape')
|
|
74
|
+
setIsFullscreen(false);
|
|
75
|
+
};
|
|
76
|
+
document.addEventListener('keydown', handleKeyDown);
|
|
77
|
+
return () => document.removeEventListener('keydown', handleKeyDown);
|
|
78
|
+
}, [isFullscreen]);
|
|
79
|
+
const activeView = views[activeIndex] ?? views[0];
|
|
80
|
+
const hasImage = Boolean(activeView);
|
|
81
|
+
const selectView = (index) => {
|
|
82
|
+
setActiveIndex(index);
|
|
83
|
+
setZoom(MIN_ZOOM);
|
|
84
|
+
setRotation(0);
|
|
85
|
+
};
|
|
86
|
+
const frame = (<section {...restProps} className={clsx('border-gray-5 dark:border-gray-1 flex min-h-0 flex-col overflow-hidden rounded-lg border', isFullscreen ? 'h-full w-full bg-white dark:bg-black' : undefined, !isFullscreen ? restProps.className : undefined)}>
|
|
87
|
+
<div className="border-gray-5 bg-gray-6 dark:border-gray-1 dark:bg-black-1 flex flex-none items-center justify-between gap-4 border-b px-4 py-3">
|
|
88
|
+
<Show>
|
|
89
|
+
<Show.When isTrue={Boolean(title)}>
|
|
90
|
+
<Paragraph size="subtitle-1" className="dark:text-white">
|
|
91
|
+
{title}
|
|
92
|
+
</Paragraph>
|
|
93
|
+
</Show.When>
|
|
94
|
+
</Show>
|
|
95
|
+
<div className="ml-auto flex items-center gap-1.5">
|
|
96
|
+
<button type="button" aria-label={labels.zoomOut} disabled={!hasImage || zoom <= MIN_ZOOM} onClick={() => setZoom((current) => current - ZOOM_STEP)} className={TOOL_CLASSNAME}>
|
|
97
|
+
<MdZoomOut aria-hidden="true"/>
|
|
98
|
+
</button>
|
|
99
|
+
<button type="button" aria-label={labels.zoomIn} disabled={!hasImage || zoom >= MAX_ZOOM} onClick={() => setZoom((current) => current + ZOOM_STEP)} className={TOOL_CLASSNAME}>
|
|
100
|
+
<MdZoomIn aria-hidden="true"/>
|
|
101
|
+
</button>
|
|
102
|
+
<button type="button" aria-label={labels.rotate} disabled={!hasImage} onClick={() => setRotation((current) => (current + QUARTER_TURN) % FULL_TURN)} className={TOOL_CLASSNAME}>
|
|
103
|
+
<MdRotateRight aria-hidden="true"/>
|
|
104
|
+
</button>
|
|
105
|
+
<button type="button" aria-label={isFullscreen ? labels.exitFullscreen : labels.enterFullscreen} aria-pressed={isFullscreen} disabled={!hasImage} onClick={() => setIsFullscreen((current) => !current)} className={TOOL_CLASSNAME}>
|
|
106
|
+
{isFullscreen ? (<MdFullscreenExit aria-hidden="true"/>) : (<MdFullscreen aria-hidden="true"/>)}
|
|
107
|
+
</button>
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
|
|
111
|
+
<Show>
|
|
112
|
+
<Show.When isTrue={views.length > 1}>
|
|
113
|
+
<List role="tablist" aria-orientation="horizontal" orientation="horizontal" className="border-gray-5 dark:border-gray-1 flex-none items-end gap-6 border-b px-4">
|
|
114
|
+
<Each of={views} render={({ id, label }, index) => (<li key={id} role="presentation">
|
|
115
|
+
<TabItem id={`${generatedId}-tab-${index}`} aria-controls={`${generatedId}-panel`} aria-selected={index === activeIndex} tabIndex={index === activeIndex ? 0 : -1} isActive={index === activeIndex} onClick={() => selectView(index)} className="pb-2">
|
|
116
|
+
{label}
|
|
117
|
+
</TabItem>
|
|
118
|
+
</li>)}/>
|
|
119
|
+
</List>
|
|
120
|
+
</Show.When>
|
|
121
|
+
</Show>
|
|
122
|
+
|
|
123
|
+
<div id={`${generatedId}-panel`} role={views.length > 1 ? 'tabpanel' : undefined} aria-labelledby={views.length > 1 ? `${generatedId}-tab-${activeIndex}` : undefined} className="bg-gray-7 dark:bg-black-2 flex min-h-0 flex-1 items-center justify-center overflow-hidden p-5">
|
|
124
|
+
<Show>
|
|
125
|
+
<Show.When isTrue={hasImage}>
|
|
126
|
+
{/**
|
|
127
|
+
* `next/image` exigiria que cada consumidor declare el dominio de
|
|
128
|
+
* sus imagenes en `remotePatterns`. Estas son cargas de usuario en
|
|
129
|
+
* almacenamiento externo, asi que la lista no se puede conocer.
|
|
130
|
+
*/}
|
|
131
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
132
|
+
<img src={activeView?.src} alt={activeView?.alt} style={{ transform: `rotate(${rotation}deg) scale(${zoom})` }} className="max-h-full max-w-full object-contain transition-transform duration-200 ease-out"/>
|
|
133
|
+
</Show.When>
|
|
134
|
+
<Show.Else>{emptyState}</Show.Else>
|
|
135
|
+
</Show>
|
|
136
|
+
</div>
|
|
137
|
+
</section>);
|
|
138
|
+
if (!isFullscreen)
|
|
139
|
+
return frame;
|
|
140
|
+
return createPortal(<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/80 p-6">
|
|
141
|
+
<div className="h-full w-full max-w-5xl">{frame}</div>
|
|
142
|
+
</div>, document.body);
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=ImageViewer.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageViewer.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/ImageViewer/ImageViewer.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EACL,SAAS,EACT,KAAK,EACL,QAAQ,GAGT,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,aAAa,EACb,QAAQ,EACR,SAAS,GACV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAwBzC,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,QAAQ,GAAG,CAAC,CAAC;AACnB,MAAM,SAAS,GAAG,GAAG,CAAC;AACtB,MAAM,YAAY,GAAG,EAAE,CAAC;AACxB,MAAM,SAAS,GAAG,GAAG,CAAC;AAEtB,MAAM,cAAc,GAClB,iUAAiU,CAAC;AAEpU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,MAAM,EACN,KAAK,EACL,UAAU,EACV,GAAG,SAAS,EACK;IACjB,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC5C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IACxD,MAAM,WAAW,GAAG,KAAK,EAAE,CAAC;IAE5B;;;;OAIG;IACH,MAAM,cAAc,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE3D,SAAS,CAAC,GAAG,EAAE;QACb,cAAc,CAAC,CAAC,CAAC,CAAC;QAClB,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClB,WAAW,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAC;IAErB,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,YAAY;YAAE,OAAO;QAE1B,MAAM,aAAa,GAAG,CAAC,KAAoB,EAAE,EAAE;YAC7C,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ;gBAAE,eAAe,CAAC,KAAK,CAAC,CAAC;QACrD,CAAC,CAAC;QAEF,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACpD,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAErC,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,EAAE;QACnC,cAAc,CAAC,KAAK,CAAC,CAAC;QACtB,OAAO,CAAC,QAAQ,CAAC,CAAC;QAClB,WAAW,CAAC,CAAC,CAAC,CAAC;IACjB,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,CACZ,CAAC,OAAO,CACN,IAAI,SAAS,CAAC,CACd,SAAS,CAAC,CAAC,IAAI,CACb,0FAA0F,EAC1F,YAAY,CAAC,CAAC,CAAC,sCAAsC,CAAC,CAAC,CAAC,SAAS,EACjE,CAAC,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAChD,CAAC,CAEF;MAAA,CAAC,GAAG,CAAC,SAAS,CAAC,iIAAiI,CAC9I;QAAA,CAAC,IAAI,CACH;UAAA,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAChC;YAAA,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,iBAAiB,CACtD;cAAA,CAAC,KAAK,CACR;YAAA,EAAE,SAAS,CACb;UAAA,EAAE,IAAI,CAAC,IAAI,CACb;QAAA,EAAE,IAAI,CACN;QAAA,CAAC,GAAG,CAAC,SAAS,CAAC,mCAAmC,CAChD;UAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAC3B,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,QAAQ,CAAC,CACxC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CACzD,SAAS,CAAC,CAAC,cAAc,CAAC,CAE1B;YAAA,CAAC,SAAS,CAAC,WAAW,CAAC,MAAM,EAC/B;UAAA,EAAE,MAAM,CACR;UAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAC1B,QAAQ,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,IAAI,QAAQ,CAAC,CACxC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CACzD,SAAS,CAAC,CAAC,cAAc,CAAC,CAE1B;YAAA,CAAC,QAAQ,CAAC,WAAW,CAAC,MAAM,EAC9B;UAAA,EAAE,MAAM,CACR;UAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAC1B,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CACpB,OAAO,CAAC,CAAC,GAAG,EAAE,CACZ,WAAW,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,YAAY,CAAC,GAAG,SAAS,CAC/D,CAAC,CACD,SAAS,CAAC,CAAC,cAAc,CAAC,CAE1B;YAAA,CAAC,aAAa,CAAC,WAAW,CAAC,MAAM,EACnC;UAAA,EAAE,MAAM,CACR;UAAA,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,UAAU,CAAC,CACT,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,eAChD,CAAC,CACD,YAAY,CAAC,CAAC,YAAY,CAAC,CAC3B,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CACpB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CACtD,SAAS,CAAC,CAAC,cAAc,CAAC,CAE1B;YAAA,CAAC,YAAY,CAAC,CAAC,CAAC,CACd,CAAC,gBAAgB,CAAC,WAAW,CAAC,MAAM,EAAG,CACxC,CAAC,CAAC,CAAC,CACF,CAAC,YAAY,CAAC,WAAW,CAAC,MAAM,EAAG,CACpC,CACH;UAAA,EAAE,MAAM,CACV;QAAA,EAAE,GAAG,CACP;MAAA,EAAE,GAAG,CAEL;;MAAA,CAAC,IAAI,CACH;QAAA,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAClC;UAAA,CAAC,IAAI,CACH,IAAI,CAAC,SAAS,CACd,gBAAgB,CAAC,YAAY,CAC7B,WAAW,CAAC,YAAY,CACxB,SAAS,CAAC,0EAA0E,CAEpF;YAAA,CAAC,IAAI,CACH,EAAE,CAAC,CAAC,KAAK,CAAC,CACV,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,CAChC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAC9B;kBAAA,CAAC,OAAO,CACN,EAAE,CAAC,CAAC,GAAG,WAAW,QAAQ,KAAK,EAAE,CAAC,CAClC,aAAa,CAAC,CAAC,GAAG,WAAW,QAAQ,CAAC,CACtC,aAAa,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,CACrC,QAAQ,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACzC,QAAQ,CAAC,CAAC,KAAK,KAAK,WAAW,CAAC,CAChC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CACjC,SAAS,CAAC,MAAM,CAEhB;oBAAA,CAAC,KAAK,CACR;kBAAA,EAAE,OAAO,CACX;gBAAA,EAAE,EAAE,CAAC,CACN,CAAC,EAEN;UAAA,EAAE,IAAI,CACR;QAAA,EAAE,IAAI,CAAC,IAAI,CACb;MAAA,EAAE,IAAI,CAEN;;MAAA,CAAC,GAAG,CACF,EAAE,CAAC,CAAC,GAAG,WAAW,QAAQ,CAAC,CAC3B,IAAI,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAChD,eAAe,CAAC,CACd,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,WAAW,QAAQ,WAAW,EAAE,CAAC,CAAC,CAAC,SAC3D,CAAC,CACD,SAAS,CAAC,+FAA+F,CAEzG;QAAA,CAAC,IAAI,CACH;UAAA,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAC1B;YAAA,CAAC;;;;WAIE,CACH;YAAA,CAAC,wDAAwD,CACzD;YAAA,CAAC,GAAG,CACF,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CACrB,GAAG,CAAC,CAAC,UAAU,EAAE,GAAG,CAAC,CACrB,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,UAAU,QAAQ,cAAc,IAAI,GAAG,EAAE,CAAC,CAC9D,SAAS,CAAC,iFAAiF,EAE/F;UAAA,EAAE,IAAI,CAAC,IAAI,CACX;UAAA,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,IAAI,CAAC,IAAI,CACpC;QAAA,EAAE,IAAI,CACR;MAAA,EAAE,GAAG,CACP;IAAA,EAAE,OAAO,CAAC,CACX,CAAC;IAEF,IAAI,CAAC,YAAY;QAAE,OAAO,KAAK,CAAC;IAEhC,OAAO,YAAY,CACjB,CAAC,GAAG,CAAC,SAAS,CAAC,qEAAqE,CAClF;MAAA,CAAC,GAAG,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CACvD;IAAA,EAAE,GAAG,CAAC,EACN,QAAQ,CAAC,IAAI,CACd,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/ImageViewer/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/02-molecules/ImageViewer/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { type HTMLAttributes, type ReactNode } from 'react';
|
|
2
|
+
export type TSideNavItem = {
|
|
3
|
+
id: string;
|
|
4
|
+
label: ReactNode;
|
|
5
|
+
indicator?: ReactNode;
|
|
6
|
+
isMuted?: boolean;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
};
|
|
9
|
+
export type TSideNavGroup = {
|
|
10
|
+
id: string;
|
|
11
|
+
items: TSideNavItem[];
|
|
12
|
+
};
|
|
13
|
+
type SideNavProps = {
|
|
14
|
+
groups: TSideNavGroup[];
|
|
15
|
+
activeId?: string;
|
|
16
|
+
onSelect: (id: string) => void;
|
|
17
|
+
navigationLabel?: string;
|
|
18
|
+
} & Omit<HTMLAttributes<HTMLElement>, 'children' | 'onSelect'>;
|
|
19
|
+
/**
|
|
20
|
+
* SideNav component for navigating between the sections of a single page.
|
|
21
|
+
*
|
|
22
|
+
* Unlike `Menu`, it does not read the route: the consumer owns which section is
|
|
23
|
+
* active. That makes it usable for panels that live inside one page, where
|
|
24
|
+
* moving between sections must not push a history entry.
|
|
25
|
+
*
|
|
26
|
+
* Groups are separated by a rule and carry no heading, so a group of one row
|
|
27
|
+
* still reads as its own thing without inventing a label for it.
|
|
28
|
+
*
|
|
29
|
+
* @component
|
|
30
|
+
* @example
|
|
31
|
+
* <SideNav
|
|
32
|
+
* navigationLabel="Sections"
|
|
33
|
+
* activeId="profile"
|
|
34
|
+
* onSelect={setSection}
|
|
35
|
+
* groups={[
|
|
36
|
+
* { id: 'general', items: [{ id: 'profile', label: 'Profile data' }] },
|
|
37
|
+
* {
|
|
38
|
+
* id: 'documents',
|
|
39
|
+
* items: [
|
|
40
|
+
* { id: 'id-card', label: 'Identity document', indicator: <MdCheck /> },
|
|
41
|
+
* { id: 'license', label: 'Driver license', isMuted: true },
|
|
42
|
+
* ],
|
|
43
|
+
* },
|
|
44
|
+
* ]}
|
|
45
|
+
* />
|
|
46
|
+
*
|
|
47
|
+
* @param {Object} props - The properties of the SideNav component.
|
|
48
|
+
* @param {TSideNavGroup[]} props.groups - Groups of rows, rendered in order and separated by a rule.
|
|
49
|
+
* @param {string} [props.activeId] - Id of the current row.
|
|
50
|
+
* @param {Function} props.onSelect - Callback triggered with the id of the selected row.
|
|
51
|
+
* @param {string} [props.navigationLabel] - Accessible name of the navigation region.
|
|
52
|
+
* @param {HTMLAttributes<HTMLElement>} [props.restProps] - Additional attributes for the nav element.
|
|
53
|
+
*
|
|
54
|
+
* @returns {ReactNode} The rendered SideNav component.
|
|
55
|
+
*/
|
|
56
|
+
export declare function SideNav({ groups, activeId, onSelect, navigationLabel, ...restProps }: SideNavProps): ReactNode;
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=SideNav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/SideNav.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,cAAc,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAItE,MAAM,MAAM,YAAY,GAAG;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,SAAS,CAAC;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,GAAG,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,UAAU,GAAG,UAAU,CAAC,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,GAAG,SAAS,EACb,EAAE,YAAY,GAAG,SAAS,CAqC1B"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import { Fragment } from 'react';
|
|
4
|
+
import { Each } from '../../00-base';
|
|
5
|
+
import { SideNavItem } from './SideNavItem';
|
|
6
|
+
/**
|
|
7
|
+
* SideNav component for navigating between the sections of a single page.
|
|
8
|
+
*
|
|
9
|
+
* Unlike `Menu`, it does not read the route: the consumer owns which section is
|
|
10
|
+
* active. That makes it usable for panels that live inside one page, where
|
|
11
|
+
* moving between sections must not push a history entry.
|
|
12
|
+
*
|
|
13
|
+
* Groups are separated by a rule and carry no heading, so a group of one row
|
|
14
|
+
* still reads as its own thing without inventing a label for it.
|
|
15
|
+
*
|
|
16
|
+
* @component
|
|
17
|
+
* @example
|
|
18
|
+
* <SideNav
|
|
19
|
+
* navigationLabel="Sections"
|
|
20
|
+
* activeId="profile"
|
|
21
|
+
* onSelect={setSection}
|
|
22
|
+
* groups={[
|
|
23
|
+
* { id: 'general', items: [{ id: 'profile', label: 'Profile data' }] },
|
|
24
|
+
* {
|
|
25
|
+
* id: 'documents',
|
|
26
|
+
* items: [
|
|
27
|
+
* { id: 'id-card', label: 'Identity document', indicator: <MdCheck /> },
|
|
28
|
+
* { id: 'license', label: 'Driver license', isMuted: true },
|
|
29
|
+
* ],
|
|
30
|
+
* },
|
|
31
|
+
* ]}
|
|
32
|
+
* />
|
|
33
|
+
*
|
|
34
|
+
* @param {Object} props - The properties of the SideNav component.
|
|
35
|
+
* @param {TSideNavGroup[]} props.groups - Groups of rows, rendered in order and separated by a rule.
|
|
36
|
+
* @param {string} [props.activeId] - Id of the current row.
|
|
37
|
+
* @param {Function} props.onSelect - Callback triggered with the id of the selected row.
|
|
38
|
+
* @param {string} [props.navigationLabel] - Accessible name of the navigation region.
|
|
39
|
+
* @param {HTMLAttributes<HTMLElement>} [props.restProps] - Additional attributes for the nav element.
|
|
40
|
+
*
|
|
41
|
+
* @returns {ReactNode} The rendered SideNav component.
|
|
42
|
+
*/
|
|
43
|
+
export function SideNav({ groups, activeId, onSelect, navigationLabel, ...restProps }) {
|
|
44
|
+
return (<nav {...restProps} aria-label={navigationLabel ?? restProps['aria-label']} className={clsx('bg-gray-6 dark:bg-black-1 flex flex-col py-4', restProps.className)}>
|
|
45
|
+
<Each of={groups} render={({ id, items }, groupIndex) => (<Fragment key={id}>
|
|
46
|
+
{groupIndex > 0 && (<hr className="border-gray-5 dark:border-gray-1 mx-4 my-2"/>)}
|
|
47
|
+
<Each of={items} render={(item) => (<SideNavItem key={item.id} isActive={item.id === activeId} isMuted={item.isMuted} indicator={item.indicator} disabled={item.disabled} onClick={() => onSelect(item.id)}>
|
|
48
|
+
{item.label}
|
|
49
|
+
</SideNavItem>)}/>
|
|
50
|
+
</Fragment>)}/>
|
|
51
|
+
</nav>);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=SideNav.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SideNav.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/SideNav.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,QAAQ,EAAuC,MAAM,OAAO,CAAC;AACtE,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAsB5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,UAAU,OAAO,CAAC,EACtB,MAAM,EACN,QAAQ,EACR,QAAQ,EACR,eAAe,EACf,GAAG,SAAS,EACC;IACb,OAAO,CACL,CAAC,GAAG,CACF,IAAI,SAAS,CAAC,CACd,UAAU,CAAC,CAAC,eAAe,IAAI,SAAS,CAAC,YAAY,CAAC,CAAC,CACvD,SAAS,CAAC,CAAC,IAAI,CACb,8CAA8C,EAC9C,SAAS,CAAC,SAAS,CACpB,CAAC,CAEF;MAAA,CAAC,IAAI,CACH,EAAE,CAAC,CAAC,MAAM,CAAC,CACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,EAAE,CAAC,CACrC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAChB;YAAA,CAAC,UAAU,GAAG,CAAC,IAAI,CACjB,CAAC,EAAE,CAAC,SAAS,CAAC,4CAA4C,EAAG,CAC9D,CACD;YAAA,CAAC,IAAI,CACH,EAAE,CAAC,CAAC,KAAK,CAAC,CACV,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAChB,CAAC,WAAW,CACV,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CACb,QAAQ,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,QAAQ,CAAC,CAC/B,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CACtB,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAC1B,QAAQ,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CACxB,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAEjC;kBAAA,CAAC,IAAI,CAAC,KAAK,CACb;gBAAA,EAAE,WAAW,CAAC,CACf,CAAC,EAEN;UAAA,EAAE,QAAQ,CAAC,CACZ,CAAC,EAEN;IAAA,EAAE,GAAG,CAAC,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
export type SideNavItemProps = {
|
|
3
|
+
isActive?: boolean;
|
|
4
|
+
isMuted?: boolean;
|
|
5
|
+
indicator?: ReactNode;
|
|
6
|
+
} & ButtonHTMLAttributes<HTMLButtonElement>;
|
|
7
|
+
/**
|
|
8
|
+
* SideNavItem component for rendering a row of a vertical navigation rail.
|
|
9
|
+
*
|
|
10
|
+
* The active row is marked with a bar on the leading edge, the vertical
|
|
11
|
+
* counterpart of the bottom bar the horizontal navigation uses.
|
|
12
|
+
*
|
|
13
|
+
* `isMuted` is for rows that exist but have nothing behind them yet. It reads
|
|
14
|
+
* as unavailable without disabling the row, so it stays reachable.
|
|
15
|
+
*
|
|
16
|
+
* @component
|
|
17
|
+
* @example
|
|
18
|
+
* <SideNavItem
|
|
19
|
+
* isActive
|
|
20
|
+
* indicator={<MdCheck />}
|
|
21
|
+
* onClick={() => select('profile')}
|
|
22
|
+
* >
|
|
23
|
+
* Profile data
|
|
24
|
+
* </SideNavItem>
|
|
25
|
+
*
|
|
26
|
+
* @param {Object} props - The properties of the SideNavItem component.
|
|
27
|
+
* @param {boolean} [props.isActive] - Whether the row is the current one.
|
|
28
|
+
* @param {boolean} [props.isMuted] - Renders the row as available but empty.
|
|
29
|
+
* @param {ReactNode} [props.indicator] - Optional element aligned to the trailing edge.
|
|
30
|
+
* @param {ReactNode} props.children - The label of the row.
|
|
31
|
+
* @param {ButtonHTMLAttributes<HTMLButtonElement>} [props.restProps] - Additional attributes for the button.
|
|
32
|
+
*
|
|
33
|
+
* @returns {ReactNode} The rendered SideNavItem component.
|
|
34
|
+
*/
|
|
35
|
+
export declare function SideNavItem({ children, isActive, isMuted, indicator, ...restProps }: SideNavItemProps): ReactNode;
|
|
36
|
+
//# sourceMappingURL=SideNavItem.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SideNavItem.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/SideNavItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,SAAS,EACb,EAAE,gBAAgB,GAAG,SAAS,CAoB9B"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import clsx from 'clsx';
|
|
2
|
+
/**
|
|
3
|
+
* SideNavItem component for rendering a row of a vertical navigation rail.
|
|
4
|
+
*
|
|
5
|
+
* The active row is marked with a bar on the leading edge, the vertical
|
|
6
|
+
* counterpart of the bottom bar the horizontal navigation uses.
|
|
7
|
+
*
|
|
8
|
+
* `isMuted` is for rows that exist but have nothing behind them yet. It reads
|
|
9
|
+
* as unavailable without disabling the row, so it stays reachable.
|
|
10
|
+
*
|
|
11
|
+
* @component
|
|
12
|
+
* @example
|
|
13
|
+
* <SideNavItem
|
|
14
|
+
* isActive
|
|
15
|
+
* indicator={<MdCheck />}
|
|
16
|
+
* onClick={() => select('profile')}
|
|
17
|
+
* >
|
|
18
|
+
* Profile data
|
|
19
|
+
* </SideNavItem>
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} props - The properties of the SideNavItem component.
|
|
22
|
+
* @param {boolean} [props.isActive] - Whether the row is the current one.
|
|
23
|
+
* @param {boolean} [props.isMuted] - Renders the row as available but empty.
|
|
24
|
+
* @param {ReactNode} [props.indicator] - Optional element aligned to the trailing edge.
|
|
25
|
+
* @param {ReactNode} props.children - The label of the row.
|
|
26
|
+
* @param {ButtonHTMLAttributes<HTMLButtonElement>} [props.restProps] - Additional attributes for the button.
|
|
27
|
+
*
|
|
28
|
+
* @returns {ReactNode} The rendered SideNavItem component.
|
|
29
|
+
*/
|
|
30
|
+
export function SideNavItem({ children, isActive, isMuted, indicator, ...restProps }) {
|
|
31
|
+
return (<button type="button" {...restProps} aria-current={isActive || undefined} className={clsx('focus-visible:ring-lavender disabled:text-gray-3 dark:disabled:text-gray-1 flex min-h-[52px] w-full cursor-pointer items-center justify-between gap-2 border-l-2 px-4 py-2 text-left text-sm focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed', isActive
|
|
32
|
+
? 'border-lavender font-medium text-black dark:text-white'
|
|
33
|
+
: 'hover:text-lavender dark:hover:text-lavender-dark border-transparent font-normal', !isActive && isMuted && 'text-gray-3 italic', !isActive && !isMuted && 'text-gray-1 dark:text-gray-2', restProps.className)}>
|
|
34
|
+
<span className="flex-1 leading-snug">{children}</span>
|
|
35
|
+
{!!indicator && <span className="flex-none">{indicator}</span>}
|
|
36
|
+
</button>);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=SideNavItem.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SideNavItem.jsx","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/SideNavItem.tsx"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,MAAM,UAAU,WAAW,CAAC,EAC1B,QAAQ,EACR,QAAQ,EACR,OAAO,EACP,SAAS,EACT,GAAG,SAAS,EACK;IACjB,OAAO,CACL,CAAC,MAAM,CACL,IAAI,CAAC,QAAQ,CACb,IAAI,SAAS,CAAC,CACd,YAAY,CAAC,CAAC,QAAQ,IAAI,SAAS,CAAC,CACpC,SAAS,CAAC,CAAC,IAAI,CACb,0QAA0Q,EAC1Q,QAAQ;YACN,CAAC,CAAC,wDAAwD;YAC1D,CAAC,CAAC,kFAAkF,EACtF,CAAC,QAAQ,IAAI,OAAO,IAAI,oBAAoB,EAC5C,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,8BAA8B,EACvD,SAAS,CAAC,SAAS,CACpB,CAAC,CAEF;MAAA,CAAC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,CACtD;MAAA,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC,CAChE;IAAA,EAAE,MAAM,CAAC,CACV,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/components/02-molecules/SideNav/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,eAAe,CAAC"}
|
|
@@ -2,6 +2,7 @@ import type { ButtonHTMLAttributes, ReactNode } from 'react';
|
|
|
2
2
|
export type TabItemProps = {
|
|
3
3
|
icon?: ReactNode | string;
|
|
4
4
|
isActive?: boolean;
|
|
5
|
+
count?: number | string;
|
|
5
6
|
} & ButtonHTMLAttributes<HTMLButtonElement>;
|
|
6
7
|
/**
|
|
7
8
|
* TabItem component for rendering a tab item with optional icon and active state.
|
|
@@ -12,6 +13,7 @@ export type TabItemProps = {
|
|
|
12
13
|
* <TabItem
|
|
13
14
|
* icon={<SomeIcon />}
|
|
14
15
|
* isActive={true}
|
|
16
|
+
* count={12}
|
|
15
17
|
* className="custom-class"
|
|
16
18
|
* >
|
|
17
19
|
* Tab Content
|
|
@@ -20,10 +22,11 @@ export type TabItemProps = {
|
|
|
20
22
|
* @param {Object} props - The properties of the TabItem component.
|
|
21
23
|
* @param {ReactNode|string} [props.icon] - Optional icon to display alongside the tab content.
|
|
22
24
|
* @param {boolean} [props.isActive] - Whether the tab item is currently active.
|
|
25
|
+
* @param {number|string} [props.count] - Optional counter rendered as plain text after the label.
|
|
23
26
|
* @param {ReactNode} props.children - The content to be displayed inside the tab item.
|
|
24
27
|
* @param {Object} [props.restProps] - Additional HTML attributes for the container div.
|
|
25
28
|
*
|
|
26
29
|
* @returns {ReactNode} The rendered TabItem component.
|
|
27
30
|
*/
|
|
28
|
-
export declare function TabItem({ children, icon, isActive, ...restProps }: TabItemProps): ReactNode;
|
|
31
|
+
export declare function TabItem({ children, icon, isActive, count, ...restProps }: TabItemProps): ReactNode;
|
|
29
32
|
//# sourceMappingURL=TabItem.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabItem.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Tab/TabItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"TabItem.d.ts","sourceRoot":"","sources":["../../../../src/components/02-molecules/Tab/TabItem.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE7D,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;AAE5C;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,OAAO,CAAC,EACtB,QAAQ,EACR,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,GAAG,SAAS,EACb,EAAE,YAAY,GAAG,SAAS,CA6B1B"}
|