@molecule/app-ui-react 1.0.0
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/LICENSE +115 -0
- package/README.md +2786 -0
- package/dist/components/Accordion.d.ts +12 -0
- package/dist/components/Accordion.d.ts.map +1 -0
- package/dist/components/Accordion.js +80 -0
- package/dist/components/Accordion.js.map +1 -0
- package/dist/components/Alert.d.ts +26 -0
- package/dist/components/Alert.d.ts.map +1 -0
- package/dist/components/Alert.js +53 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AuthGuard.d.ts +66 -0
- package/dist/components/AuthGuard.d.ts.map +1 -0
- package/dist/components/AuthGuard.js +42 -0
- package/dist/components/AuthGuard.js.map +1 -0
- package/dist/components/Avatar.d.ts +12 -0
- package/dist/components/Avatar.d.ts.map +1 -0
- package/dist/components/Avatar.js +25 -0
- package/dist/components/Avatar.js.map +1 -0
- package/dist/components/Badge.d.ts +12 -0
- package/dist/components/Badge.d.ts.map +1 -0
- package/dist/components/Badge.js +18 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +12 -0
- package/dist/components/Button.d.ts.map +1 -0
- package/dist/components/Button.js +19 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.d.ts +34 -0
- package/dist/components/Card.d.ts.map +1 -0
- package/dist/components/Card.js +71 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/Checkbox.d.ts +12 -0
- package/dist/components/Checkbox.d.ts.map +1 -0
- package/dist/components/Checkbox.js +41 -0
- package/dist/components/Checkbox.js.map +1 -0
- package/dist/components/Dropdown.d.ts +38 -0
- package/dist/components/Dropdown.d.ts.map +1 -0
- package/dist/components/Dropdown.js +352 -0
- package/dist/components/Dropdown.js.map +1 -0
- package/dist/components/EmptyState.d.ts +15 -0
- package/dist/components/EmptyState.d.ts.map +1 -0
- package/dist/components/EmptyState.js +20 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/FloatingInput.d.ts +22 -0
- package/dist/components/FloatingInput.d.ts.map +1 -0
- package/dist/components/FloatingInput.js +38 -0
- package/dist/components/FloatingInput.js.map +1 -0
- package/dist/components/Form.d.ts +22 -0
- package/dist/components/Form.d.ts.map +1 -0
- package/dist/components/Form.js +81 -0
- package/dist/components/Form.js.map +1 -0
- package/dist/components/Icon.d.ts +48 -0
- package/dist/components/Icon.d.ts.map +1 -0
- package/dist/components/Icon.js +46 -0
- package/dist/components/Icon.js.map +1 -0
- package/dist/components/Input.d.ts +12 -0
- package/dist/components/Input.d.ts.map +1 -0
- package/dist/components/Input.js +25 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/LanguagePicker.d.ts +60 -0
- package/dist/components/LanguagePicker.d.ts.map +1 -0
- package/dist/components/LanguagePicker.js +45 -0
- package/dist/components/LanguagePicker.js.map +1 -0
- package/dist/components/Layout.d.ts +24 -0
- package/dist/components/Layout.d.ts.map +1 -0
- package/dist/components/Layout.js +104 -0
- package/dist/components/Layout.js.map +1 -0
- package/dist/components/Modal.d.ts +32 -0
- package/dist/components/Modal.d.ts.map +1 -0
- package/dist/components/Modal.js +235 -0
- package/dist/components/Modal.js.map +1 -0
- package/dist/components/PageHeader.d.ts +15 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +20 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PageShell.d.ts +15 -0
- package/dist/components/PageShell.d.ts.map +1 -0
- package/dist/components/PageShell.js +20 -0
- package/dist/components/PageShell.js.map +1 -0
- package/dist/components/Pagination.d.ts +12 -0
- package/dist/components/Pagination.d.ts.map +1 -0
- package/dist/components/Pagination.js +78 -0
- package/dist/components/Pagination.js.map +1 -0
- package/dist/components/PanelClose.d.ts +40 -0
- package/dist/components/PanelClose.d.ts.map +1 -0
- package/dist/components/PanelClose.js +32 -0
- package/dist/components/PanelClose.js.map +1 -0
- package/dist/components/Progress.d.ts +45 -0
- package/dist/components/Progress.d.ts.map +1 -0
- package/dist/components/Progress.js +21 -0
- package/dist/components/Progress.js.map +1 -0
- package/dist/components/RadioGroup.d.ts +12 -0
- package/dist/components/RadioGroup.d.ts.map +1 -0
- package/dist/components/RadioGroup.js +34 -0
- package/dist/components/RadioGroup.js.map +1 -0
- package/dist/components/Select.d.ts +12 -0
- package/dist/components/Select.d.ts.map +1 -0
- package/dist/components/Select.js +57 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/Separator.d.ts +25 -0
- package/dist/components/Separator.d.ts.map +1 -0
- package/dist/components/Separator.js +18 -0
- package/dist/components/Separator.js.map +1 -0
- package/dist/components/SidebarUserCard.d.ts +60 -0
- package/dist/components/SidebarUserCard.d.ts.map +1 -0
- package/dist/components/SidebarUserCard.js +45 -0
- package/dist/components/SidebarUserCard.js.map +1 -0
- package/dist/components/Skeleton.d.ts +26 -0
- package/dist/components/Skeleton.d.ts.map +1 -0
- package/dist/components/Skeleton.js +45 -0
- package/dist/components/Skeleton.js.map +1 -0
- package/dist/components/Spinner.d.ts +17 -0
- package/dist/components/Spinner.d.ts.map +1 -0
- package/dist/components/Spinner.js +32 -0
- package/dist/components/Spinner.js.map +1 -0
- package/dist/components/Switch.d.ts +12 -0
- package/dist/components/Switch.d.ts.map +1 -0
- package/dist/components/Switch.js +52 -0
- package/dist/components/Switch.js.map +1 -0
- package/dist/components/Table.d.ts +12 -0
- package/dist/components/Table.d.ts.map +1 -0
- package/dist/components/Table.js +53 -0
- package/dist/components/Table.js.map +1 -0
- package/dist/components/Tabs.d.ts +12 -0
- package/dist/components/Tabs.d.ts.map +1 -0
- package/dist/components/Tabs.js +72 -0
- package/dist/components/Tabs.js.map +1 -0
- package/dist/components/Textarea.d.ts +12 -0
- package/dist/components/Textarea.d.ts.map +1 -0
- package/dist/components/Textarea.js +66 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/ThemeToggle.d.ts +43 -0
- package/dist/components/ThemeToggle.d.ts.map +1 -0
- package/dist/components/ThemeToggle.js +30 -0
- package/dist/components/ThemeToggle.js.map +1 -0
- package/dist/components/Toast.d.ts +61 -0
- package/dist/components/Toast.d.ts.map +1 -0
- package/dist/components/Toast.js +159 -0
- package/dist/components/Toast.js.map +1 -0
- package/dist/components/Tooltip.d.ts +21 -0
- package/dist/components/Tooltip.d.ts.map +1 -0
- package/dist/components/Tooltip.js +245 -0
- package/dist/components/Tooltip.js.map +1 -0
- package/dist/components/UserMenu.d.ts +59 -0
- package/dist/components/UserMenu.d.ts.map +1 -0
- package/dist/components/UserMenu.js +34 -0
- package/dist/components/UserMenu.js.map +1 -0
- package/dist/components/UserMenuPopover.d.ts +139 -0
- package/dist/components/UserMenuPopover.d.ts.map +1 -0
- package/dist/components/UserMenuPopover.js +173 -0
- package/dist/components/UserMenuPopover.js.map +1 -0
- package/dist/components/index.d.ts +43 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +43 -0
- package/dist/components/index.js.map +1 -0
- package/dist/index.d.ts +131 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +7 -0
- package/dist/types.js.map +1 -0
- package/dist/utilities/index.d.ts +8 -0
- package/dist/utilities/index.d.ts.map +1 -0
- package/dist/utilities/index.js +8 -0
- package/dist/utilities/index.js.map +1 -0
- package/dist/utilities/initials.d.ts +13 -0
- package/dist/utilities/initials.d.ts.map +1 -0
- package/dist/utilities/initials.js +23 -0
- package/dist/utilities/initials.js.map +1 -0
- package/dist/utilities/renderIcon.d.ts +21 -0
- package/dist/utilities/renderIcon.d.ts.map +1 -0
- package/dist/utilities/renderIcon.js +40 -0
- package/dist/utilities/renderIcon.js.map +1 -0
- package/dist/utilities.d.ts +12 -0
- package/dist/utilities.d.ts.map +1 -0
- package/dist/utilities.js +14 -0
- package/dist/utilities.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* RadioGroup component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef, useId } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
/**
|
|
11
|
+
* RadioGroup component.
|
|
12
|
+
*/
|
|
13
|
+
export const RadioGroup = forwardRef(({ options, value, onChange, size: _size, label, name, direction = 'vertical', error, className, style, testId, disabled, }, ref) => {
|
|
14
|
+
const cm = getClassMap();
|
|
15
|
+
// Radios only form a native group (arrow-key navigation, exclusive
|
|
16
|
+
// native checked state) when they share a `name` — and that name must be
|
|
17
|
+
// UNIQUE per group. The old `label`-as-name fallback merged every group
|
|
18
|
+
// sharing a visible label (e.g. two "Size" pickers) into ONE native
|
|
19
|
+
// group: selecting in one silently deselected the other. Callers that
|
|
20
|
+
// need a specific submitted field name pass the `name` prop.
|
|
21
|
+
const generatedName = useId();
|
|
22
|
+
const groupName = name || generatedName;
|
|
23
|
+
const errorId = `${groupName}-error`;
|
|
24
|
+
const handleChange = (optionValue) => {
|
|
25
|
+
onChange?.(optionValue);
|
|
26
|
+
};
|
|
27
|
+
return (_jsxs("div", { ref: ref, className: className, style: style, "data-testid": testId, role: "radiogroup", "aria-label": label ?? t('ui.radioGroup.label', undefined, { defaultValue: 'Radio group' }), "aria-invalid": error ? true : undefined, "aria-describedby": error ? errorId : undefined, children: [label && (_jsx("div", { className: cm.cn(cm.label({ required: false }), cm.sp('mb', 2)), children: label })), _jsx("div", { className: cm.radioGroupLayout(direction), children: options.map((option) => {
|
|
28
|
+
const isChecked = value === option.value;
|
|
29
|
+
const isDisabled = disabled || option.disabled;
|
|
30
|
+
return (_jsxs("label", { className: cm.cn(cm.controlLabel, isDisabled && cm.controlDisabled), children: [_jsx("input", { type: "radio", name: groupName, value: option.value, checked: isChecked, disabled: isDisabled, onChange: () => handleChange(option.value), "data-state": isChecked ? 'checked' : 'unchecked', className: cm.cn(cm.radio({ error: !!error }), cm.cursorPointer) }), _jsx("span", { className: cm.controlText, children: option.label })] }, option.value));
|
|
31
|
+
}) }), error && (_jsx("p", { id: errorId, className: cm.cn(cm.formError, cm.sp('mt', 1)), children: error }))] }));
|
|
32
|
+
});
|
|
33
|
+
RadioGroup.displayName = 'RadioGroup';
|
|
34
|
+
//# sourceMappingURL=RadioGroup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RadioGroup.js","sourceRoot":"","sources":["../../src/components/RadioGroup.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Select component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { SelectProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Select component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Select: React.ForwardRefExoticComponent<SelectProps<string> & React.RefAttributes<HTMLSelectElement>>;
|
|
12
|
+
//# sourceMappingURL=Select.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAA4B,MAAM,OAAO,CAAA;AAGhD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAKnD;;GAEG;AACH,eAAO,MAAM,MAAM,+FA2JlB,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Select component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef, useId } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
import { renderIcon } from '../utilities/renderIcon.js';
|
|
11
|
+
/**
|
|
12
|
+
* Select component.
|
|
13
|
+
*/
|
|
14
|
+
export const Select = forwardRef(({ options, value, onValueChange, size = 'md', label, placeholder, error, hint, clearable, className, style, testId, disabled, required, name, id, onChange, ...rest }, ref) => {
|
|
15
|
+
const cm = getClassMap();
|
|
16
|
+
// Fall back to a generated id so label htmlFor / aria-describedby never
|
|
17
|
+
// point at `undefined-error` (which also collides across multiple
|
|
18
|
+
// id-less selects on the same page).
|
|
19
|
+
const generatedId = useId();
|
|
20
|
+
const selectId = id || name || generatedId;
|
|
21
|
+
const selectClasses = cm.cn(cm.select({ error: !!error, size }), cm.selectNative, cm.inputPadRight, className);
|
|
22
|
+
// The clearable "no selection" option shares value="" with the
|
|
23
|
+
// placeholder option — rendering both produced two <option value="">
|
|
24
|
+
// entries in the same <select>. Suppress the redundant one; the
|
|
25
|
+
// placeholder already serves as the clear target.
|
|
26
|
+
const showClearOption = clearable && !placeholder;
|
|
27
|
+
// Group options by group property
|
|
28
|
+
const groupedOptions = options.reduce((acc, option) => {
|
|
29
|
+
const group = option.group || '';
|
|
30
|
+
if (!acc[group]) {
|
|
31
|
+
acc[group] = [];
|
|
32
|
+
}
|
|
33
|
+
acc[group].push(option);
|
|
34
|
+
return acc;
|
|
35
|
+
}, {});
|
|
36
|
+
const handleChange = (e) => {
|
|
37
|
+
onChange?.(e);
|
|
38
|
+
onValueChange?.(e.target.value);
|
|
39
|
+
};
|
|
40
|
+
const renderOptions = () => {
|
|
41
|
+
const groups = Object.entries(groupedOptions);
|
|
42
|
+
if (groups.length === 1 && groups[0][0] === '') {
|
|
43
|
+
// No groups, render flat options
|
|
44
|
+
return groups[0][1].map((option) => (_jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)));
|
|
45
|
+
}
|
|
46
|
+
// Render grouped options
|
|
47
|
+
return groups.map(([group, groupOptions]) => {
|
|
48
|
+
if (group === '') {
|
|
49
|
+
return groupOptions.map((option) => (_jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value)));
|
|
50
|
+
}
|
|
51
|
+
return (_jsx("optgroup", { label: group, children: groupOptions.map((option) => (_jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))) }, group));
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
return (_jsxs("div", { className: cm.inputWrapper, children: [label && (_jsx("label", { htmlFor: selectId, className: cm.cn(cm.label({ required: !!required }), cm.labelBlock), children: label })), _jsxs("div", { className: cm.inputInner, children: [_jsxs("select", { ref: ref, id: selectId, name: name, value: value, disabled: disabled, required: required, "aria-invalid": !!error, "aria-describedby": error ? `${selectId}-error` : hint ? `${selectId}-hint` : undefined, className: selectClasses, style: style, "data-testid": testId, onChange: handleChange, ...rest, children: [placeholder && (_jsx("option", { value: "", disabled: true, children: placeholder })), showClearOption && (_jsx("option", { value: "", children: t('ui.select.clear', undefined, { defaultValue: '--' }) })), renderOptions()] }), _jsx("div", { className: cm.inputRightElement, style: { pointerEvents: 'none' }, children: renderIcon('chevron-down', cm.cn(cm.iconSm, cm.textMuted)) })] }), error && (_jsx("p", { id: `${selectId}-error`, className: cm.formError, children: error })), hint && !error && (_jsx("p", { id: `${selectId}-hint`, className: cm.formHint, children: hint }))] }));
|
|
55
|
+
});
|
|
56
|
+
Select.displayName = 'Select';
|
|
57
|
+
//# sourceMappingURL=Select.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Select.js","sourceRoot":"","sources":["../../src/components/Select.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Separator component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { BaseProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Props for the Separator component.
|
|
10
|
+
*/
|
|
11
|
+
export interface SeparatorProps extends BaseProps {
|
|
12
|
+
/**
|
|
13
|
+
* Orientation of the separator.
|
|
14
|
+
*/
|
|
15
|
+
orientation?: 'horizontal' | 'vertical';
|
|
16
|
+
/**
|
|
17
|
+
* Decorative separators are purely visual.
|
|
18
|
+
*/
|
|
19
|
+
decorative?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Separator component.
|
|
23
|
+
*/
|
|
24
|
+
export declare const Separator: React.ForwardRefExoticComponent<SeparatorProps & React.RefAttributes<HTMLDivElement>>;
|
|
25
|
+
//# sourceMappingURL=Separator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.d.ts","sourceRoot":"","sources":["../../src/components/Separator.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAGjD;;GAEG;AACH,MAAM,WAAW,cAAe,SAAQ,SAAS;IAC/C;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IAEvC;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,uFAgBrB,CAAA"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Separator component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
9
|
+
/**
|
|
10
|
+
* Separator component.
|
|
11
|
+
*/
|
|
12
|
+
export const Separator = forwardRef(({ orientation = 'horizontal', decorative = true, className, style, testId }, ref) => {
|
|
13
|
+
const cm = getClassMap();
|
|
14
|
+
const separatorClasses = cm.cn(cm.separator({ orientation }), className);
|
|
15
|
+
return (_jsx("div", { ref: ref, role: decorative ? 'none' : 'separator', "aria-orientation": decorative ? undefined : orientation, className: separatorClasses, style: style, "data-testid": testId }));
|
|
16
|
+
});
|
|
17
|
+
Separator.displayName = 'Separator';
|
|
18
|
+
//# sourceMappingURL=Separator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Separator.js","sourceRoot":"","sources":["../../src/components/Separator.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAiB9C;;GAEG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,UAAU,CACjC,CAAC,EAAE,WAAW,GAAG,YAAY,EAAE,UAAU,GAAG,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE;IACnF,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,gBAAgB,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;IAExE,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,sBACrB,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,EACtD,SAAS,EAAE,gBAAgB,EAC3B,KAAK,EAAE,KAAK,iBACC,MAAM,GACnB,CACH,CAAA;AACH,CAAC,CACF,CAAA;AAED,SAAS,CAAC,WAAW,GAAG,WAAW,CAAA"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SidebarUserCard component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { ButtonHTMLAttributes, JSX, ReactNode } from 'react';
|
|
7
|
+
/**
|
|
8
|
+
* Props for the {@link SidebarUserCard} component.
|
|
9
|
+
*
|
|
10
|
+
* Extends standard `<button>` attributes so callers can pass extra
|
|
11
|
+
* `data-*`, `aria-*`, `style`, or event handler props onto the trigger
|
|
12
|
+
* button without forking. The named props below cover the common
|
|
13
|
+
* customization points.
|
|
14
|
+
*/
|
|
15
|
+
export interface SidebarUserCardProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, 'aria-label' | 'onClick' | 'children'> {
|
|
16
|
+
/**
|
|
17
|
+
* Panel content shown inside the drawer/modal (typically the app's
|
|
18
|
+
* `SettingsPanel`). It can dismiss the drawer by calling
|
|
19
|
+
* `usePanelClose()` — no `onClose` prop-threading required.
|
|
20
|
+
*/
|
|
21
|
+
children: ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* Display name override. When omitted, falls back to
|
|
24
|
+
* `useAuth().user?.name`, then `email`, then a guest label.
|
|
25
|
+
*/
|
|
26
|
+
name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Secondary line under the name (role, plan, status, etc.).
|
|
29
|
+
* Apps typically pass something like `t('sidebar.memberStatus', {}, { defaultValue: 'Premium Member' })`.
|
|
30
|
+
* When omitted and the auth user has an email, the email is shown instead.
|
|
31
|
+
*/
|
|
32
|
+
secondaryLine?: string;
|
|
33
|
+
/** Optional avatar image URL — overrides `useAuth().user?.avatarUrl`. */
|
|
34
|
+
avatarUrl?: string;
|
|
35
|
+
/** i18n key for the trigger button's aria-label. Default: `'sidebarUserCard.open'`. */
|
|
36
|
+
ariaLabelKey?: string;
|
|
37
|
+
/** Fallback aria-label if the i18n key is missing. Default: `'Open account menu'`. */
|
|
38
|
+
ariaLabelDefault?: string;
|
|
39
|
+
/**
|
|
40
|
+
* `data-mol-id` for the trigger button. Defaults to
|
|
41
|
+
* `'sidebar-user-card'`. Pass a different value (e.g. `'user-menu'`)
|
|
42
|
+
* to disambiguate or align with an app's existing e2e selectors.
|
|
43
|
+
*/
|
|
44
|
+
dataMolId?: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Sidebar-resident user-account card: avatar + name + status line, opens
|
|
48
|
+
* the app's settings drawer on click.
|
|
49
|
+
*
|
|
50
|
+
* Drop-in replacement for `<UserMenu />` when the trigger lives inside a
|
|
51
|
+
* vertical sidebar (e.g. as the `userMenu` slot of `<SidebarLayout>`).
|
|
52
|
+
* Reads name/email/avatar from `useAuth()` by default; pass explicit
|
|
53
|
+
* `name` / `secondaryLine` / `avatarUrl` props to override.
|
|
54
|
+
*
|
|
55
|
+
* Ships with `data-mol-id="sidebar-user-card"` on the trigger button
|
|
56
|
+
* by default for AI-agent / e2e selection. Callers can override by
|
|
57
|
+
* passing `data-mol-id` as an extra prop.
|
|
58
|
+
*/
|
|
59
|
+
export declare function SidebarUserCard({ children, name, secondaryLine, avatarUrl, ariaLabelKey, ariaLabelDefault, dataMolId, className, ...rest }: SidebarUserCardProps): JSX.Element;
|
|
60
|
+
//# sourceMappingURL=SidebarUserCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarUserCard.d.ts","sourceRoot":"","sources":["../../src/components/SidebarUserCard.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAoBjE;;;;;;;GAOG;AACH,MAAM,WAAW,oBAAqB,SAAQ,IAAI,CAChD,oBAAoB,CAAC,iBAAiB,CAAC,EACvC,YAAY,GAAG,SAAS,GAAG,UAAU,CACtC;IACC;;;;OAIG;IACH,QAAQ,EAAE,SAAS,CAAA;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,sFAAsF;IACtF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,SAAS,EACT,YAAqC,EACrC,gBAAsC,EACtC,SAA+B,EAC/B,SAAS,EACT,GAAG,IAAI,EACR,EAAE,oBAAoB,GAAG,GAAG,CAAC,OAAO,CA+EpC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
import { useLocation } from 'react-router';
|
|
4
|
+
import { useAuth, useTranslation } from '@molecule/app-react';
|
|
5
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
6
|
+
import { getInitials } from '../utilities/initials.js';
|
|
7
|
+
import { Modal } from './Modal.js';
|
|
8
|
+
import { PanelCloseProvider } from './PanelClose.js';
|
|
9
|
+
/**
|
|
10
|
+
* Sidebar-resident user-account card: avatar + name + status line, opens
|
|
11
|
+
* the app's settings drawer on click.
|
|
12
|
+
*
|
|
13
|
+
* Drop-in replacement for `<UserMenu />` when the trigger lives inside a
|
|
14
|
+
* vertical sidebar (e.g. as the `userMenu` slot of `<SidebarLayout>`).
|
|
15
|
+
* Reads name/email/avatar from `useAuth()` by default; pass explicit
|
|
16
|
+
* `name` / `secondaryLine` / `avatarUrl` props to override.
|
|
17
|
+
*
|
|
18
|
+
* Ships with `data-mol-id="sidebar-user-card"` on the trigger button
|
|
19
|
+
* by default for AI-agent / e2e selection. Callers can override by
|
|
20
|
+
* passing `data-mol-id` as an extra prop.
|
|
21
|
+
*/
|
|
22
|
+
export function SidebarUserCard({ children, name, secondaryLine, avatarUrl, ariaLabelKey = 'sidebarUserCard.open', ariaLabelDefault = 'Open account menu', dataMolId = 'sidebar-user-card', className, ...rest }) {
|
|
23
|
+
const cm = getClassMap();
|
|
24
|
+
const { t } = useTranslation();
|
|
25
|
+
const auth = useAuth();
|
|
26
|
+
const user = auth.user;
|
|
27
|
+
const [open, setOpen] = useState(false);
|
|
28
|
+
const location = useLocation();
|
|
29
|
+
// Close the drawer whenever the route changes. React Router updates
|
|
30
|
+
// `location` on both in-app navigation and browser back/forward
|
|
31
|
+
// (popstate), so a single effect covers both — without it the drawer
|
|
32
|
+
// stays mounted over the next page and blocks clicks underneath.
|
|
33
|
+
useEffect(() => {
|
|
34
|
+
setOpen(false);
|
|
35
|
+
}, [location.pathname, location.search]);
|
|
36
|
+
const guestName = t('sidebarUserCard.guest', {}, { defaultValue: 'Guest' });
|
|
37
|
+
const displayName = name ?? user?.name ?? user?.email ?? guestName;
|
|
38
|
+
const displaySecondary = secondaryLine ?? user?.email ?? undefined;
|
|
39
|
+
const displayAvatarUrl = avatarUrl ?? user?.avatarUrl ?? undefined;
|
|
40
|
+
return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: () => setOpen(true), "aria-label": t(ariaLabelKey, {}, { defaultValue: ariaLabelDefault }), "data-mol-id": dataMolId, className: cm.cn(cm.flex({ align: 'center', gap: 'sm' }), cm.sp('px', 3), cm.sp('py', 3), 'w-full text-left rounded-xl bg-surface-container-low hover:bg-surface-container transition-colors', className), ...rest, children: [displayAvatarUrl ? (_jsx("img", { src: displayAvatarUrl, alt: "", className: cm.cn(cm.w(10), cm.h(10), cm.roundedFull, 'shrink-0 object-cover') })) : (_jsx("span", { "aria-hidden": "true", className: cm.cn(cm.w(10), cm.h(10), cm.roundedFull, cm.flex({ align: 'center', justify: 'center' }), cm.textSize('sm'), cm.fontWeight('bold'), 'shrink-0'), style: {
|
|
41
|
+
backgroundColor: 'var(--color-primary)',
|
|
42
|
+
color: 'var(--color-on-primary, #ffffff)',
|
|
43
|
+
}, children: getInitials(displayName) })), _jsxs("span", { className: cm.cn('min-w-0 flex-1'), children: [_jsx("span", { className: cm.cn(cm.textSize('sm'), cm.fontWeight('semibold'), 'block truncate'), children: displayName }), displaySecondary ? (_jsx("span", { className: cm.cn(cm.textSize('xs'), 'block truncate text-on-surface-variant'), children: displaySecondary })) : null] })] }), _jsx(Modal, { open: open, onClose: () => setOpen(false), className: cm.drawer, children: _jsx(PanelCloseProvider, { close: () => setOpen(false), children: children }) })] }));
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=SidebarUserCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SidebarUserCard.js","sourceRoot":"","sources":["../../src/components/SidebarUserCard.tsx"],"names":[],"mappings":";AAOA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1C,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAA;AAC7D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAClC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AAsDpD;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAAC,EAC9B,QAAQ,EACR,IAAI,EACJ,aAAa,EACb,SAAS,EACT,YAAY,GAAG,sBAAsB,EACrC,gBAAgB,GAAG,mBAAmB,EACtC,SAAS,GAAG,mBAAmB,EAC/B,SAAS,EACT,GAAG,IAAI,EACc;IACrB,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,EAAE,CAAC,EAAE,GAAG,cAAc,EAAE,CAAA;IAC9B,MAAM,IAAI,GAAG,OAAO,EAAoB,CAAA;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACtB,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAE9B,oEAAoE;IACpE,gEAAgE;IAChE,qEAAqE;IACrE,iEAAiE;IACjE,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,CAAA;IAChB,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAExC,MAAM,SAAS,GAAG,CAAC,CAAC,uBAAuB,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,OAAO,EAAE,CAAC,CAAA;IAC3E,MAAM,WAAW,GAAG,IAAI,IAAI,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,KAAK,IAAI,SAAS,CAAA;IAClE,MAAM,gBAAgB,GAAG,aAAa,IAAI,IAAI,EAAE,KAAK,IAAI,SAAS,CAAA;IAClE,MAAM,gBAAgB,GAAG,SAAS,IAAI,IAAI,EAAE,SAAS,IAAI,SAAS,CAAA;IAElE,OAAO,CACL,8BACE,kBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,gBAChB,CAAC,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,YAAY,EAAE,gBAAgB,EAAE,CAAC,iBACtD,SAAS,EACtB,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EACvC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,EACd,mGAAmG,EACnG,SAAS,CACV,KACG,IAAI,aAEP,gBAAgB,CAAC,CAAC,CAAC,CAClB,cACE,GAAG,EAAE,gBAAgB,EACrB,GAAG,EAAC,EAAE,EACN,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,WAAW,EAAE,uBAAuB,CAAC,GAC7E,CACH,CAAC,CAAC,CAAC,CACF,8BACc,MAAM,EAClB,SAAS,EAAE,EAAE,CAAC,EAAE,CACd,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACR,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EACR,EAAE,CAAC,WAAW,EACd,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAC/C,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EACjB,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EACrB,UAAU,CACX,EACD,KAAK,EAAE;4BACL,eAAe,EAAE,sBAAsB;4BACvC,KAAK,EAAE,kCAAkC;yBAC1C,YAEA,WAAW,CAAC,WAAW,CAAC,GACpB,CACR,EACD,gBAAM,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,aACtC,eAAM,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,YACnF,WAAW,GACP,EACN,gBAAgB,CAAC,CAAC,CAAC,CAClB,eAAM,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,wCAAwC,CAAC,YAChF,gBAAgB,GACZ,CACR,CAAC,CAAC,CAAC,IAAI,IACH,IACA,EACT,KAAC,KAAK,IAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,CAAC,MAAM,YACpE,KAAC,kBAAkB,IAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,YAAG,QAAQ,GAAsB,GAC1E,IACP,CACJ,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skeleton component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { SkeletonProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Skeleton component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Skeleton: React.ForwardRefExoticComponent<SkeletonProps & React.RefAttributes<HTMLDivElement>>;
|
|
12
|
+
/**
|
|
13
|
+
* Skeleton text line.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SkeletonText: React.ForwardRefExoticComponent<{
|
|
16
|
+
lines?: number;
|
|
17
|
+
className?: string;
|
|
18
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
19
|
+
/**
|
|
20
|
+
* Skeleton circle (avatar placeholder).
|
|
21
|
+
*/
|
|
22
|
+
export declare const SkeletonCircle: React.ForwardRefExoticComponent<{
|
|
23
|
+
size?: number;
|
|
24
|
+
className?: string;
|
|
25
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
26
|
+
//# sourceMappingURL=Skeleton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.d.ts","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAEzC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAGrD;;GAEG;AACH,eAAO,MAAM,QAAQ,sFA8BpB,CAAA;AAID;;GAEG;AACH,eAAO,MAAM,YAAY;YAAwC,MAAM;gBAAc,MAAM;wCAY1F,CAAA;AAID;;GAEG;AACH,eAAO,MAAM,cAAc;WAAuC,MAAM;gBAAc,MAAM;wCAI3F,CAAA"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Skeleton component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
9
|
+
/**
|
|
10
|
+
* Skeleton component.
|
|
11
|
+
*/
|
|
12
|
+
export const Skeleton = forwardRef(({ width, height, circle, borderRadius, animation = 'pulse', className, style, testId }, ref) => {
|
|
13
|
+
const cm = getClassMap();
|
|
14
|
+
const skeletonClasses = cm.cn(cm.skeleton(), circle && cm.skeletonCircle, animation === 'none' && cm.skeletonNone, animation === 'wave' && cm.skeletonWave, className);
|
|
15
|
+
const computedStyle = {
|
|
16
|
+
...style,
|
|
17
|
+
width: typeof width === 'number' ? `${width}px` : width,
|
|
18
|
+
height: typeof height === 'number' ? `${height}px` : height,
|
|
19
|
+
borderRadius: circle
|
|
20
|
+
? '9999px'
|
|
21
|
+
: typeof borderRadius === 'number'
|
|
22
|
+
? `${borderRadius}px`
|
|
23
|
+
: borderRadius,
|
|
24
|
+
};
|
|
25
|
+
// If circle, make width and height equal
|
|
26
|
+
if (circle && width && !height) {
|
|
27
|
+
computedStyle.height = computedStyle.width;
|
|
28
|
+
}
|
|
29
|
+
return _jsx("div", { ref: ref, className: skeletonClasses, style: computedStyle, "data-testid": testId });
|
|
30
|
+
});
|
|
31
|
+
Skeleton.displayName = 'Skeleton';
|
|
32
|
+
/**
|
|
33
|
+
* Skeleton text line.
|
|
34
|
+
*/
|
|
35
|
+
export const SkeletonText = forwardRef(({ lines = 3, className }, ref) => {
|
|
36
|
+
const cm = getClassMap();
|
|
37
|
+
return (_jsx("div", { ref: ref, className: cm.cn(cm.skeletonTextContainer, className), children: Array.from({ length: lines }).map((_, i) => (_jsx(Skeleton, { height: 16, width: i === lines - 1 ? '60%' : '100%' }, i))) }));
|
|
38
|
+
});
|
|
39
|
+
SkeletonText.displayName = 'SkeletonText';
|
|
40
|
+
/**
|
|
41
|
+
* Skeleton circle (avatar placeholder).
|
|
42
|
+
*/
|
|
43
|
+
export const SkeletonCircle = forwardRef(({ size = 40, className }, ref) => (_jsx(Skeleton, { ref: ref, circle: true, width: size, height: size, className: className })));
|
|
44
|
+
SkeletonCircle.displayName = 'SkeletonCircle';
|
|
45
|
+
//# sourceMappingURL=Skeleton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.js","sourceRoot":"","sources":["../../src/components/Skeleton.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;GAEG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAChC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,SAAS,GAAG,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,EAAE;IAC9F,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IAExB,MAAM,eAAe,GAAG,EAAE,CAAC,EAAE,CAC3B,EAAE,CAAC,QAAQ,EAAE,EACb,MAAM,IAAI,EAAE,CAAC,cAAc,EAC3B,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,YAAY,EACvC,SAAS,KAAK,MAAM,IAAI,EAAE,CAAC,YAAY,EACvC,SAAS,CACV,CAAA;IAED,MAAM,aAAa,GAAwB;QACzC,GAAG,KAAK;QACR,KAAK,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK;QACvD,MAAM,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,MAAM;QAC3D,YAAY,EAAE,MAAM;YAClB,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,OAAO,YAAY,KAAK,QAAQ;gBAChC,CAAC,CAAC,GAAG,YAAY,IAAI;gBACrB,CAAC,CAAC,YAAY;KACnB,CAAA;IAED,yCAAyC;IACzC,IAAI,MAAM,IAAI,KAAK,IAAI,CAAC,MAAM,EAAE,CAAC;QAC/B,aAAa,CAAC,MAAM,GAAG,aAAa,CAAC,KAAK,CAAA;IAC5C,CAAC;IAED,OAAO,cAAK,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,iBAAe,MAAM,GAAI,CAAA;AACjG,CAAC,CACF,CAAA;AAED,QAAQ,CAAC,WAAW,GAAG,UAAU,CAAA;AAEjC;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CACpC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE;IAChC,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IAExB,OAAO,CACL,cAAK,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,qBAAqB,EAAE,SAAS,CAAC,YACjE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAC3C,KAAC,QAAQ,IAAS,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,IAAtD,CAAC,CAAyD,CAC1E,CAAC,GACE,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,YAAY,CAAC,WAAW,GAAG,cAAc,CAAA;AAEzC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CACtC,CAAC,EAAE,IAAI,GAAG,EAAE,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,EAAE,CAAC,CACjC,KAAC,QAAQ,IAAC,GAAG,EAAE,GAAG,EAAE,MAAM,QAAC,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,GAAI,CAC/E,CACF,CAAA;AAED,cAAc,CAAC,WAAW,GAAG,gBAAgB,CAAA"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { SpinnerProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Spinner component.
|
|
10
|
+
*
|
|
11
|
+
* Extracts data-* and aria-* props from the rest spread so callers can
|
|
12
|
+
* pass `data-mol-id`, custom `aria-*` overrides, etc. without forking.
|
|
13
|
+
*/
|
|
14
|
+
export declare const Spinner: React.ForwardRefExoticComponent<SpinnerProps & {
|
|
15
|
+
'data-mol-id'?: string;
|
|
16
|
+
} & React.RefAttributes<HTMLDivElement>>;
|
|
17
|
+
//# sourceMappingURL=Spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAGzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAGpD;;;;;GAKG;AACH,eAAO,MAAM,OAAO;oBAA+D,MAAM;wCA+BxF,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Spinner component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
/**
|
|
11
|
+
* Spinner component.
|
|
12
|
+
*
|
|
13
|
+
* Extracts data-* and aria-* props from the rest spread so callers can
|
|
14
|
+
* pass `data-mol-id`, custom `aria-*` overrides, etc. without forking.
|
|
15
|
+
*/
|
|
16
|
+
export const Spinner = forwardRef(({ size = 'md', color, label, className, style, testId, ...rest }, ref) => {
|
|
17
|
+
const cm = getClassMap();
|
|
18
|
+
const classes = cm.cn(cm.spinner({ size }), className);
|
|
19
|
+
const colorStyle = color &&
|
|
20
|
+
typeof color === 'string' &&
|
|
21
|
+
!['primary', 'secondary', 'success', 'warning', 'error', 'info'].includes(color)
|
|
22
|
+
? { borderColor: color, borderTopColor: 'transparent' }
|
|
23
|
+
: undefined;
|
|
24
|
+
const passthrough = {};
|
|
25
|
+
for (const [k, v] of Object.entries(rest)) {
|
|
26
|
+
if (k.startsWith('data-') || k.startsWith('aria-'))
|
|
27
|
+
passthrough[k] = v;
|
|
28
|
+
}
|
|
29
|
+
return (_jsx("div", { ref: ref, role: "status", "aria-label": label || t('ui.spinner.loading', undefined, { defaultValue: 'Loading' }), className: classes, style: { ...style, ...colorStyle }, "data-testid": testId, ...passthrough, children: label && _jsx("span", { className: cm.srOnly, children: label }) }));
|
|
30
|
+
});
|
|
31
|
+
Spinner.displayName = 'Spinner';
|
|
32
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../src/components/Spinner.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAEzC,OAAO,EAAE,CAAC,EAAE,MAAM,oBAAoB,CAAA;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,UAAU,CAC/B,CAAC,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE;IACxE,MAAM,EAAE,GAAG,WAAW,EAAE,CAAA;IACxB,MAAM,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,CAAC,CAAA;IAEtD,MAAM,UAAU,GACd,KAAK;QACL,OAAO,KAAK,KAAK,QAAQ;QACzB,CAAC,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;QAC9E,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE;QACvD,CAAC,CAAC,SAAS,CAAA;IAEf,MAAM,WAAW,GAA4B,EAAE,CAAA;IAC/C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAA+B,CAAC,EAAE,CAAC;QACrE,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACxE,CAAC;IAED,OAAO,CACL,cACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAC,QAAQ,gBACD,KAAK,IAAI,CAAC,CAAC,oBAAoB,EAAE,SAAS,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC,EACpF,SAAS,EAAE,OAAO,EAClB,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,GAAG,UAAU,EAAE,iBACrB,MAAM,KACf,WAAW,YAEd,KAAK,IAAI,eAAM,SAAS,EAAE,EAAE,CAAC,MAAM,YAAG,KAAK,GAAQ,GAChD,CACP,CAAA;AACH,CAAC,CACF,CAAA;AAED,OAAO,CAAC,WAAW,GAAG,SAAS,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Switch component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { SwitchProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Switch component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Switch: React.ForwardRefExoticComponent<SwitchProps & React.RefAttributes<HTMLButtonElement>>;
|
|
12
|
+
//# sourceMappingURL=Switch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Switch.d.ts","sourceRoot":"","sources":["../../src/components/Switch.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAwC,MAAM,OAAO,CAAA;AAE5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAGnD;;GAEG;AACH,eAAO,MAAM,MAAM,uFA+ElB,CAAA"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Switch component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef, useEffect, useRef } from 'react';
|
|
8
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
9
|
+
/**
|
|
10
|
+
* Switch component.
|
|
11
|
+
*/
|
|
12
|
+
export const Switch = forwardRef(({ label, checked, size = 'md', color, className, style, testId, disabled, onChange, ...rest }, ref) => {
|
|
13
|
+
const cm = getClassMap();
|
|
14
|
+
const state = checked ? 'checked' : 'unchecked';
|
|
15
|
+
// A hidden, real native checkbox mirrors `checked` — `handleClick`
|
|
16
|
+
// below calls `.click()` on it instead of forging a fake event object.
|
|
17
|
+
// Its `change` is a GENUINE browser Event, so
|
|
18
|
+
// `event.preventDefault()`/`event.stopPropagation()` are real methods
|
|
19
|
+
// (no more "not a function" crash) and `event.target`/`currentTarget`
|
|
20
|
+
// resolve to a real element with a real `.checked` — matching the
|
|
21
|
+
// `(e.target as HTMLInputElement).checked` pattern every flagship
|
|
22
|
+
// template's onChange already uses against this component. The old
|
|
23
|
+
// `{ target: { checked } } as unknown as Event` cast happened to read
|
|
24
|
+
// back OK for that one property but crashed on any real Event method.
|
|
25
|
+
// Kept as a SIBLING of the visible <label> (not a descendant of it) —
|
|
26
|
+
// both the checkbox and the <button> are "labelable" elements per the
|
|
27
|
+
// HTML spec, so nesting both inside one <label> risks the browser's
|
|
28
|
+
// native label-click-forwarding firing a SECOND, redundant click on
|
|
29
|
+
// whichever one isn't the direct target.
|
|
30
|
+
const hiddenInputRef = useRef(null);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const input = hiddenInputRef.current;
|
|
33
|
+
if (!input || !onChange)
|
|
34
|
+
return;
|
|
35
|
+
const listener = (event) => onChange(event);
|
|
36
|
+
input.addEventListener('change', listener);
|
|
37
|
+
return () => input.removeEventListener('change', listener);
|
|
38
|
+
}, [onChange]);
|
|
39
|
+
const handleClick = () => {
|
|
40
|
+
if (!disabled) {
|
|
41
|
+
hiddenInputRef.current?.click();
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
return (_jsxs(_Fragment, { children: [_jsx("input", { ref: hiddenInputRef, type: "checkbox", checked: !!checked, disabled: disabled, "aria-hidden": "true", tabIndex: -1, className: cm.srOnly,
|
|
45
|
+
// Controlled input requires an onChange to silence React's
|
|
46
|
+
// dev warning; the REAL forwarding to the caller happens through
|
|
47
|
+
// the native `addEventListener('change', …)` above (a genuine
|
|
48
|
+
// browser Event), not through this synthetic React handler.
|
|
49
|
+
onChange: () => { } }), _jsxs("label", { className: cm.cn(cm.controlLabel, disabled && cm.controlDisabled), children: [_jsx("button", { ref: ref, type: "button", role: "switch", "aria-checked": !!checked, disabled: disabled, "data-state": state, onClick: handleClick, className: cm.cn(cm.switchBase({ size, color }), className), style: style, "data-testid": testId, ...rest, children: _jsx("span", { "data-state": state, className: cm.switchThumb({ size }) }) }), !!label && _jsx("span", { className: cm.controlText, children: label })] })] }));
|
|
50
|
+
});
|
|
51
|
+
Switch.displayName = 'Switch';
|
|
52
|
+
//# sourceMappingURL=Switch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Switch.js","sourceRoot":"","sources":["../../src/components/Switch.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Table component.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import type { TableProps } from '@molecule/app-ui';
|
|
8
|
+
/**
|
|
9
|
+
* Table component.
|
|
10
|
+
*/
|
|
11
|
+
export declare const Table: React.ForwardRefExoticComponent<TableProps<Record<string, unknown>> & React.RefAttributes<HTMLTableElement>>;
|
|
12
|
+
//# sourceMappingURL=Table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.d.ts","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAqB,MAAM,OAAO,CAAA;AAGzC,OAAO,KAAK,EAAe,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAM/D;;GAEG;AACH,eAAO,MAAM,KAAK,8GA4IjB,CAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Table component.
|
|
4
|
+
*
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { forwardRef } from 'react';
|
|
8
|
+
import { t } from '@molecule/app-i18n';
|
|
9
|
+
import { getClassMap } from '@molecule/app-ui';
|
|
10
|
+
import { renderIcon } from '../utilities/renderIcon.js';
|
|
11
|
+
import { Spinner } from './Spinner.js';
|
|
12
|
+
/**
|
|
13
|
+
* Table component.
|
|
14
|
+
*/
|
|
15
|
+
export const Table = forwardRef(({ data, columns, rowKey, bordered, striped, hoverable = true, size: _size, emptyContent, loading, sort, onSort, onRowClick, className, style, testId, }, ref) => {
|
|
16
|
+
const cm = getClassMap();
|
|
17
|
+
const getRowKey = (row, index) => {
|
|
18
|
+
if (typeof rowKey === 'function') {
|
|
19
|
+
return rowKey(row);
|
|
20
|
+
}
|
|
21
|
+
if (rowKey && row[rowKey] !== undefined) {
|
|
22
|
+
return row[rowKey];
|
|
23
|
+
}
|
|
24
|
+
return index;
|
|
25
|
+
};
|
|
26
|
+
const getCellValue = (row, column, index) => {
|
|
27
|
+
if (column.render) {
|
|
28
|
+
return column.render(row[column.key], row, index);
|
|
29
|
+
}
|
|
30
|
+
return row[column.key];
|
|
31
|
+
};
|
|
32
|
+
const handleSort = (column) => {
|
|
33
|
+
if (!column.sortable || !onSort)
|
|
34
|
+
return;
|
|
35
|
+
const key = column.key;
|
|
36
|
+
const currentDirection = sort?.key === key ? sort.direction : undefined;
|
|
37
|
+
const newDirection = currentDirection === 'asc' ? 'desc' : 'asc';
|
|
38
|
+
onSort(key, newDirection);
|
|
39
|
+
};
|
|
40
|
+
const tableClasses = cm.cn(cm.table, bordered && cm.tableBordered, className);
|
|
41
|
+
return (_jsxs("div", { className: cm.tableWrapper, children: [loading && (_jsx("div", { className: cm.tableLoadingOverlay, children: _jsx(Spinner, { size: "lg" }) })), _jsxs("table", { ref: ref, className: tableClasses, style: style, "data-testid": testId, children: [_jsx("thead", { className: cm.tableHeader, children: _jsx("tr", { className: cm.tableRow, children: columns.map((column) => (_jsx("th", { className: cm.cn(cm.tableHead, column.align === 'center' && cm.textCenter, column.align === 'right' && cm.textRight, column.sortable && cm.tableHeadSortable), style: { width: column.width }, onClick: () => column.sortable && handleSort(column), "aria-sort": column.sortable
|
|
42
|
+
? sort?.key === column.key
|
|
43
|
+
? sort.direction === 'asc'
|
|
44
|
+
? 'ascending'
|
|
45
|
+
: 'descending'
|
|
46
|
+
: 'none'
|
|
47
|
+
: undefined, children: _jsxs("div", { className: cm.tableSortWrapper, children: [column.header, column.sortable && sort?.key === column.key && (_jsx("span", { className: cm.tableSortIcon, children: sort.direction === 'asc'
|
|
48
|
+
? renderIcon('chevron-up', cm.iconSm)
|
|
49
|
+
: renderIcon('chevron-down', cm.iconSm) }))] }) }, column.key))) }) }), _jsx("tbody", { className: cm.tableBody, children: data.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: columns.length, className: cm.tableEmptyCell, children: emptyContent ||
|
|
50
|
+
t('ui.table.empty', undefined, { defaultValue: 'No data available' }) }) })) : (data.map((row, rowIndex) => (_jsx("tr", { className: cm.cn(cm.tableRow, striped && rowIndex % 2 === 1 && cm.tableRowStriped, hoverable && cm.tableRowHoverable, onRowClick && cm.tableRowClickable), onClick: () => onRowClick?.(row, rowIndex), children: columns.map((column) => (_jsx("td", { className: cm.cn(cm.tableCell, column.align === 'center' && cm.textCenter, column.align === 'right' && cm.textRight), children: getCellValue(row, column, rowIndex) }, column.key))) }, getRowKey(row, rowIndex))))) })] })] }));
|
|
51
|
+
});
|
|
52
|
+
Table.displayName = 'Table';
|
|
53
|
+
//# sourceMappingURL=Table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Table.js","sourceRoot":"","sources":["../../src/components/Table.tsx"],"names":[],"mappings":"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"}
|