@stfrigerio/sito-template 0.1.6 → 0.1.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/dist/components/molecules/SearchBar/SearchBar.d.ts +11 -2
- package/dist/components/molecules/SearchBar/SearchBar.d.ts.map +1 -1
- package/dist/components/molecules/SearchBar/index.d.ts +1 -1
- package/dist/components/molecules/SearchBar/index.d.ts.map +1 -1
- package/dist/components/molecules/Tabs/Tabs.d.ts +11 -5
- package/dist/components/molecules/Tabs/Tabs.d.ts.map +1 -1
- package/dist/components/molecules/ThemeSwitcher/ThemeSwitcher.d.ts +9 -2
- package/dist/components/molecules/ThemeSwitcher/ThemeSwitcher.d.ts.map +1 -1
- package/dist/components/molecules/index.d.ts +3 -2
- package/dist/components/molecules/index.d.ts.map +1 -1
- package/dist/components/organisms/charts/PieChart/PieChart.d.ts +2 -0
- package/dist/components/organisms/charts/PieChart/PieChart.d.ts.map +1 -1
- package/dist/components/organisms/charts/QuantifiableHabitsChart/QuantifiableHabitsChart.d.ts.map +1 -1
- package/dist/components/organisms/charts/SunburstChart/SunburstChart.d.ts +2 -0
- package/dist/components/organisms/charts/SunburstChart/SunburstChart.d.ts.map +1 -1
- package/dist/index.esm.js +177 -45
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +177 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export
|
|
2
|
+
export interface FilterOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon: React.ElementType;
|
|
6
|
+
}
|
|
3
7
|
export interface SearchResult {
|
|
4
8
|
id: string;
|
|
5
9
|
type: string;
|
|
@@ -10,13 +14,18 @@ export interface SearchResult {
|
|
|
10
14
|
export interface SearchBarProps {
|
|
11
15
|
className?: string;
|
|
12
16
|
placeholder?: string;
|
|
13
|
-
onSearch?: (query: string, filter:
|
|
17
|
+
onSearch?: (query: string, filter: string) => Promise<SearchResult[]>;
|
|
14
18
|
onResultClick?: (result: SearchResult) => void;
|
|
15
19
|
onClear?: () => void;
|
|
16
20
|
debounceDelay?: number;
|
|
17
21
|
minSearchLength?: number;
|
|
18
22
|
showFilter?: boolean;
|
|
19
23
|
enableKeyboardShortcut?: boolean;
|
|
24
|
+
filterOptions?: FilterOption[];
|
|
25
|
+
entityIcons?: {
|
|
26
|
+
[key: string]: React.ElementType;
|
|
27
|
+
};
|
|
20
28
|
}
|
|
29
|
+
export type SearchFilter = 'all' | 'projects' | 'clients' | 'contacts' | 'interactions' | 'team';
|
|
21
30
|
export declare const SearchBar: React.FC<SearchBarProps>;
|
|
22
31
|
//# sourceMappingURL=SearchBar.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SearchBar.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchBar/SearchBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,MAAM,
|
|
1
|
+
{"version":3,"file":"SearchBar.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchBar/SearchBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAKxE,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,WAAW,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC3B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IACtE,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAC/C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,aAAa,CAAC,EAAE,YAAY,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,KAAK,CAAC,WAAW,CAAA;KAAE,CAAC;CACtD;AAqBD,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,cAAc,GAAG,MAAM,CAAC;AAEjG,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAuV9C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchBar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/SearchBar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export interface Tab {
|
|
3
|
+
id: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon?: React.ComponentType<any> | React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export interface TabsProps {
|
|
8
|
+
activeTab: string;
|
|
9
|
+
onTabChange: (tab: string) => void;
|
|
10
|
+
tabs?: Tab[];
|
|
11
|
+
className?: string;
|
|
6
12
|
}
|
|
13
|
+
export type TabType = 'details' | 'github' | 'jira' | 'functional';
|
|
7
14
|
export declare const Tabs: React.FC<TabsProps>;
|
|
8
|
-
export {};
|
|
9
15
|
//# sourceMappingURL=Tabs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/Tabs/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,WAAW,GAAG;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC;CACrD;AAED,MAAM,WAAW,SAAS;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAWD,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,YAAY,CAAC;AAEnE,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CAgDpC,CAAC"}
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface
|
|
2
|
+
export interface ThemeOption {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
icon: React.ReactNode;
|
|
6
|
+
}
|
|
7
|
+
export interface ThemeSwitcherProps {
|
|
3
8
|
variant?: 'button' | 'dropdown' | 'toggle';
|
|
4
9
|
showLabel?: boolean;
|
|
5
10
|
className?: string;
|
|
11
|
+
currentTheme?: string;
|
|
12
|
+
onThemeChange?: (theme: string) => void;
|
|
13
|
+
themes?: ThemeOption[];
|
|
6
14
|
}
|
|
7
15
|
export declare const ThemeSwitcher: React.FC<ThemeSwitcherProps>;
|
|
8
|
-
export {};
|
|
9
16
|
//# sourceMappingURL=ThemeSwitcher.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeSwitcher.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/ThemeSwitcher/ThemeSwitcher.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,
|
|
1
|
+
{"version":3,"file":"ThemeSwitcher.d.ts","sourceRoot":"","sources":["../../../../src/components/molecules/ThemeSwitcher/ThemeSwitcher.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,WAAW,WAAW;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC;CACzB;AAED,MAAM,WAAW,kBAAkB;IAC/B,OAAO,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IAC3C,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAsHtD,CAAC"}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export { EditFAB } from './EditFAB';
|
|
2
2
|
export type { EditFABProps } from './EditFAB';
|
|
3
3
|
export { SearchBar } from './SearchBar';
|
|
4
|
-
export type { SearchBarProps } from './SearchBar';
|
|
4
|
+
export type { SearchBarProps, FilterOption, SearchResult, SearchFilter } from './SearchBar';
|
|
5
5
|
export { TimeInput } from './TimeInput';
|
|
6
6
|
export type { TimeInputProps } from './TimeInput';
|
|
7
7
|
export { ThemeSwitcher } from './ThemeSwitcher/ThemeSwitcher';
|
|
8
|
+
export type { ThemeSwitcherProps, ThemeOption } from './ThemeSwitcher/ThemeSwitcher';
|
|
8
9
|
export { Tabs } from './Tabs/Tabs';
|
|
9
|
-
export type {
|
|
10
|
+
export type { TabsProps, Tab } from './Tabs/Tabs';
|
|
10
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/molecules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/molecules/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,YAAY,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5F,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,YAAY,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAErF,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AACnC,YAAY,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PieChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/PieChart/PieChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAIhD,UAAU,YAAY;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,aAAa;IACnB,IAAI,EAAE,YAAY,EAAE,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;CACvB;
|
|
1
|
+
{"version":3,"file":"PieChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/PieChart/PieChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4B,MAAM,OAAO,CAAA;AAIhD,UAAU,YAAY;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,aAAa;IACnB,IAAI,EAAE,YAAY,EAAE,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAsBD,eAAO,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAoL5C,CAAA"}
|
package/dist/components/organisms/charts/QuantifiableHabitsChart/QuantifiableHabitsChart.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"QuantifiableHabitsChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/QuantifiableHabitsChart/QuantifiableHabitsChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAA;AAInE,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;AAOnE,UAAU,SAAS;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;CACvC;AAED,UAAU,4BAA4B;IAClC,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,QAAQ,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;IAC9D,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACvC,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAC1C;AAcD,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,
|
|
1
|
+
{"version":3,"file":"QuantifiableHabitsChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/QuantifiableHabitsChart/QuantifiableHabitsChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAA;AAInE,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAA;AAOnE,UAAU,SAAS;IACf,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAA;CACvC;AAED,UAAU,4BAA4B;IAClC,IAAI,EAAE,SAAS,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,QAAQ,CAAA;IAC1B,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAA;IAC9D,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACvC,WAAW,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;CAC1C;AAcD,eAAO,MAAM,uBAAuB,EAAE,KAAK,CAAC,EAAE,CAAC,4BAA4B,CA8T1E,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SunburstChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/SunburstChart/SunburstChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAA;AAIzD,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;CAC9B;AAED,UAAU,kBAAkB;IACxB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"SunburstChart.d.ts","sourceRoot":"","sources":["../../../../../src/components/organisms/charts/SunburstChart/SunburstChart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAqC,MAAM,OAAO,CAAA;AAIzD,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAA;CAC9B;AAED,UAAU,kBAAkB;IACxB,IAAI,EAAE,cAAc,CAAA;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;CACvB;AAqBD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwNtD,CAAA"}
|
package/dist/index.esm.js
CHANGED
|
@@ -1178,7 +1178,8 @@ const EditFAB = ({ canEdit, isEditMode, hasUnsavedChanges = false, isSaving = fa
|
|
|
1178
1178
|
|
|
1179
1179
|
var styles$a = {"searchContainer":"SearchBar-module_searchContainer__TdM1w","searchInputWrapper":"SearchBar-module_searchInputWrapper__kCZLU","searchIcon":"SearchBar-module_searchIcon__IIxEu","searchInput":"SearchBar-module_searchInput__V4gkE","clearButton":"SearchBar-module_clearButton__7fNIY","filterSelect":"SearchBar-module_filterSelect__xIVE4","resultsDropdown":"SearchBar-module_resultsDropdown__yh6NF","loadingState":"SearchBar-module_loadingState__4gidK","emptyState":"SearchBar-module_emptyState__RbI4s","spinner":"SearchBar-module_spinner__PMc6-","resultsGroups":"SearchBar-module_resultsGroups__U24DC","resultGroup":"SearchBar-module_resultGroup__SoTQH","groupHeader":"SearchBar-module_groupHeader__bFRHA","groupIcon":"SearchBar-module_groupIcon__9ENM-","groupTitle":"SearchBar-module_groupTitle__ZekZs","groupCount":"SearchBar-module_groupCount__PQIqw","groupResults":"SearchBar-module_groupResults__xTF52","resultItem":"SearchBar-module_resultItem__VaKKy","highlighted":"SearchBar-module_highlighted__Q-3sH","resultTitle":"SearchBar-module_resultTitle__i1uqL","resultSubtitle":"SearchBar-module_resultSubtitle__LQOJ1","resultMeta":"SearchBar-module_resultMeta__Kmkrn","resultContent":"SearchBar-module_resultContent__TzVzL","highlight":"SearchBar-module_highlight__Q3PSP"};
|
|
1180
1180
|
|
|
1181
|
-
|
|
1181
|
+
// Default filter options for backwards compatibility
|
|
1182
|
+
const defaultFilterOptions = [
|
|
1182
1183
|
{ value: 'all', label: 'All', icon: FiSearch },
|
|
1183
1184
|
{ value: 'projects', label: 'Projects', icon: FiFolder },
|
|
1184
1185
|
{ value: 'clients', label: 'Clients', icon: FiUsers },
|
|
@@ -1186,16 +1187,18 @@ const filterOptions = [
|
|
|
1186
1187
|
{ value: 'interactions', label: 'Interactions', icon: FiMessageSquare },
|
|
1187
1188
|
{ value: 'team', label: 'Team', icon: FiUserPlus },
|
|
1188
1189
|
];
|
|
1189
|
-
const
|
|
1190
|
+
const defaultEntityIcons = {
|
|
1190
1191
|
projects: FiFolder,
|
|
1191
1192
|
clients: FiUsers,
|
|
1192
1193
|
contacts: FiBook,
|
|
1193
1194
|
interactions: FiMessageSquare,
|
|
1194
1195
|
team: FiUserPlus,
|
|
1195
1196
|
};
|
|
1196
|
-
const SearchBar = ({ className, placeholder = "Search (Ctrl+Space)...", onSearch, onResultClick, onClear, debounceDelay = 300, minSearchLength = 2, showFilter = true, enableKeyboardShortcut = true }) => {
|
|
1197
|
+
const SearchBar = ({ className, placeholder = "Search (Ctrl+Space)...", onSearch, onResultClick, onClear, debounceDelay = 300, minSearchLength = 2, showFilter = true, enableKeyboardShortcut = true, filterOptions: customFilterOptions, entityIcons: customEntityIcons }) => {
|
|
1198
|
+
const filterOptions = customFilterOptions ?? defaultFilterOptions;
|
|
1199
|
+
const entityIcons = customEntityIcons ?? defaultEntityIcons;
|
|
1197
1200
|
const [query, setQuery] = useState('');
|
|
1198
|
-
const [filter, setFilter] = useState('all');
|
|
1201
|
+
const [filter, setFilter] = useState(filterOptions[0]?.value ?? 'all');
|
|
1199
1202
|
const [results, setResults] = useState([]);
|
|
1200
1203
|
const [isLoading, setIsLoading] = useState(false);
|
|
1201
1204
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
@@ -1479,9 +1482,19 @@ const useTheme = () => {
|
|
|
1479
1482
|
|
|
1480
1483
|
var styles$7 = {"button":"ThemeSwitcher-module_button__VfRjU","iconWrapper":"ThemeSwitcher-module_iconWrapper__FpHo8","label":"ThemeSwitcher-module_label__2Hfkp","toggle":"ThemeSwitcher-module_toggle__ATXx4","toggleTrack":"ThemeSwitcher-module_toggleTrack__x28Rv","toggleThumb":"ThemeSwitcher-module_toggleThumb__V8QeN","dropdown":"ThemeSwitcher-module_dropdown__3qLdt","dropdownTrigger":"ThemeSwitcher-module_dropdownTrigger__UzYV5","dropdownMenu":"ThemeSwitcher-module_dropdownMenu__3L5hT","dropdownItem":"ThemeSwitcher-module_dropdownItem__inw-K","active":"ThemeSwitcher-module_active__OHP19","icon":"ThemeSwitcher-module_icon__iRZiJ","text":"ThemeSwitcher-module_text__OCOoA"};
|
|
1481
1484
|
|
|
1482
|
-
const ThemeSwitcher = ({ variant = 'button', showLabel = false, className = '', }) => {
|
|
1483
|
-
|
|
1484
|
-
const
|
|
1485
|
+
const ThemeSwitcher = ({ variant = 'button', showLabel = false, className = '', currentTheme, onThemeChange, themes: customThemes, }) => {
|
|
1486
|
+
// Try to use internal context if available, otherwise use props
|
|
1487
|
+
const contextTheme = (() => {
|
|
1488
|
+
try {
|
|
1489
|
+
return useTheme();
|
|
1490
|
+
}
|
|
1491
|
+
catch {
|
|
1492
|
+
return null;
|
|
1493
|
+
}
|
|
1494
|
+
})();
|
|
1495
|
+
const theme = currentTheme ?? contextTheme?.theme ?? 'light';
|
|
1496
|
+
const setTheme = onThemeChange ?? contextTheme?.setTheme ?? (() => { });
|
|
1497
|
+
const defaultThemes = [
|
|
1485
1498
|
{ value: 'light', label: 'Light', icon: jsx(FiSun, {}) },
|
|
1486
1499
|
{ value: 'dark', label: 'Dark', icon: jsx(FiMoon, {}) },
|
|
1487
1500
|
{ value: 'lossito', label: 'Lossito Light', icon: '✨' },
|
|
@@ -1489,21 +1502,22 @@ const ThemeSwitcher = ({ variant = 'button', showLabel = false, className = '',
|
|
|
1489
1502
|
{ value: 'dmood', label: 'Dmood Light', icon: '💙' },
|
|
1490
1503
|
{ value: 'dmood-dark', label: 'Dmood Dark', icon: '🌌' },
|
|
1491
1504
|
];
|
|
1505
|
+
const themes = customThemes ?? defaultThemes;
|
|
1492
1506
|
const currentThemeIndex = themes.findIndex(t => t.value === theme);
|
|
1493
|
-
const
|
|
1507
|
+
const currentThemeData = themes[currentThemeIndex] ?? themes[0];
|
|
1494
1508
|
if (variant === 'toggle') {
|
|
1495
1509
|
// Simple toggle between light and dark
|
|
1496
1510
|
const isDark = theme.includes('dark');
|
|
1497
1511
|
return (jsxs(motion.button, { className: `${styles$7.toggle} ${className}`, onClick: () => setTheme(isDark ? 'light' : 'dark'), whileTap: { scale: 0.95 }, "aria-label": "Toggle theme", children: [jsx(motion.div, { className: styles$7.toggleTrack, animate: { backgroundColor: isDark ? 'var(--color-primary)' : 'var(--color-border)' }, children: jsx(motion.div, { className: styles$7.toggleThumb, animate: { x: isDark ? 24 : 0 }, transition: { type: 'spring', stiffness: 500, damping: 30 }, children: isDark ? jsx(FiMoon, { size: 14 }) : jsx(FiSun, { size: 14 }) }) }), showLabel && jsx("span", { className: styles$7.label, children: isDark ? 'Dark' : 'Light' })] }));
|
|
1498
1512
|
}
|
|
1499
1513
|
if (variant === 'dropdown') {
|
|
1500
|
-
return (jsxs("div", { className: `${styles$7.dropdown} ${className}`, children: [jsxs(motion.button, { className: styles$7.dropdownTrigger, whileTap: { scale: 0.98 }, children: [
|
|
1514
|
+
return (jsxs("div", { className: `${styles$7.dropdown} ${className}`, children: [jsxs(motion.button, { className: styles$7.dropdownTrigger, whileTap: { scale: 0.98 }, children: [currentThemeData.icon, showLabel && jsx("span", { className: styles$7.label, children: currentThemeData.label })] }), jsx(motion.div, { className: styles$7.dropdownMenu, initial: { opacity: 0, y: -10 }, animate: { opacity: 1, y: 0 }, children: themes.map((t) => (jsxs(motion.button, { className: `${styles$7.dropdownItem} ${theme === t.value ? styles$7.active : ''}`, onClick: () => setTheme(t.value), whileHover: { x: 4 }, whileTap: { scale: 0.98 }, children: [jsx("span", { className: styles$7.icon, children: t.icon }), jsx("span", { className: styles$7.text, children: t.label })] }, t.value))) })] }));
|
|
1501
1515
|
}
|
|
1502
1516
|
// Default button variant - cycles through themes
|
|
1503
1517
|
return (jsxs(motion.button, { className: `${styles$7.button} ${className}`, onClick: () => {
|
|
1504
1518
|
const nextIndex = (currentThemeIndex + 1) % themes.length;
|
|
1505
1519
|
setTheme(themes[nextIndex].value);
|
|
1506
|
-
}, whileTap: { scale: 0.95 }, whileHover: { scale: 1.05 }, "aria-label": `Current theme: ${
|
|
1520
|
+
}, whileTap: { scale: 0.95 }, whileHover: { scale: 1.05 }, "aria-label": `Current theme: ${currentThemeData.label}. Click to change.`, children: [jsx(motion.div, { initial: { rotate: -180, opacity: 0 }, animate: { rotate: 0, opacity: 1 }, exit: { rotate: 180, opacity: 0 }, transition: { duration: 0.3 }, className: styles$7.iconWrapper, children: currentThemeData.icon }, theme), showLabel && jsx("span", { className: styles$7.label, children: currentThemeData.label })] }));
|
|
1507
1521
|
};
|
|
1508
1522
|
|
|
1509
1523
|
// THIS FILE IS AUTO GENERATED
|
|
@@ -1513,15 +1527,16 @@ function SiJira (props) {
|
|
|
1513
1527
|
|
|
1514
1528
|
var styles$6 = {"tabs":"Tabs-module_tabs__Vlvn7","tab":"Tabs-module_tab__uQKim","tabIcon":"Tabs-module_tabIcon__AgN-O"};
|
|
1515
1529
|
|
|
1516
|
-
|
|
1530
|
+
// Default tabs for backwards compatibility
|
|
1531
|
+
const defaultTabs = [
|
|
1517
1532
|
{ id: 'details', icon: FiInfo, label: 'Dettagli' },
|
|
1518
1533
|
{ id: 'github', icon: FiGithub, label: 'GitHub' },
|
|
1519
1534
|
{ id: 'jira', icon: SiJira, label: 'Jira' },
|
|
1520
1535
|
{ id: 'functional', icon: FiInfo, label: 'Analisi funzionale' }
|
|
1521
1536
|
];
|
|
1522
|
-
const Tabs = ({ activeTab, onTabChange }) => {
|
|
1523
|
-
|
|
1524
|
-
|
|
1537
|
+
const Tabs = ({ activeTab, onTabChange, tabs: customTabs, className = '' }) => {
|
|
1538
|
+
const tabs = customTabs ?? defaultTabs;
|
|
1539
|
+
return (jsx("div", { className: `${styles$6.tabs} ${className}`, children: tabs.map((tab) => {
|
|
1525
1540
|
const isActive = activeTab === tab.id;
|
|
1526
1541
|
return (jsxs(motion.button, { className: styles$6.tab, "data-active": isActive, onClick: () => onTabChange(tab.id), style: { position: 'relative' }, children: [jsx(motion.div, { animate: {
|
|
1527
1542
|
rotate: isActive ? [0, -10, 10, -5, 5, 0] : 0,
|
|
@@ -1530,7 +1545,7 @@ const Tabs = ({ activeTab, onTabChange }) => {
|
|
|
1530
1545
|
duration: 0.5,
|
|
1531
1546
|
ease: 'easeInOut'
|
|
1532
1547
|
}
|
|
1533
|
-
}, children: jsx(
|
|
1548
|
+
}, children: tab.icon && (typeof tab.icon === 'function' ? (jsx("span", { className: styles$6.tabIcon, children: React.createElement(tab.icon) })) : (jsx("span", { className: styles$6.tabIcon, children: tab.icon }))) }), jsx("span", { children: tab.label })] }, tab.id));
|
|
1534
1549
|
}) }));
|
|
1535
1550
|
};
|
|
1536
1551
|
|
|
@@ -2214,11 +2229,22 @@ const BooleansHeatmap = ({ data, habitName, width = 800, height = 200, habitColo
|
|
|
2214
2229
|
var styles$1 = {"container":"SunburstChart-module_container__w1ZYc","title":"SunburstChart-module_title__T6Ak7","chart":"SunburstChart-module_chart__BFM6E","tooltip":"SunburstChart-module_tooltip__TuTAN"};
|
|
2215
2230
|
|
|
2216
2231
|
const COLOR_PALETTE = [
|
|
2217
|
-
'#
|
|
2218
|
-
'#
|
|
2219
|
-
'#
|
|
2232
|
+
'#6366f1', '#8b5cf6', '#06b6d4', '#10b981',
|
|
2233
|
+
'#f59e0b', '#ef4444', '#ec4899', '#84cc16',
|
|
2234
|
+
'#f97316', '#3b82f6', '#14b8a6', '#f59e0b'
|
|
2220
2235
|
];
|
|
2221
|
-
|
|
2236
|
+
// Calculate text color based on background luminance for optimal contrast
|
|
2237
|
+
const getTextColor$1 = (backgroundColor) => {
|
|
2238
|
+
const color = d3.color(backgroundColor);
|
|
2239
|
+
if (!color)
|
|
2240
|
+
return '#ffffff';
|
|
2241
|
+
const rgb = color.rgb();
|
|
2242
|
+
// Calculate relative luminance using WCAG formula
|
|
2243
|
+
const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
|
|
2244
|
+
// Return white text for dark backgrounds, black for light backgrounds
|
|
2245
|
+
return luminance > 0.5 ? '#000000' : '#ffffff';
|
|
2246
|
+
};
|
|
2247
|
+
const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Chart', tagColors = {}, unit = 'items', centerLabel }) => {
|
|
2222
2248
|
const svgRef = useRef(null);
|
|
2223
2249
|
const colorMap = useRef(new Map()).current;
|
|
2224
2250
|
const colorIndex = useRef(0);
|
|
@@ -2261,7 +2287,8 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2261
2287
|
.startAngle(d => d.x0)
|
|
2262
2288
|
.endAngle(d => d.x1)
|
|
2263
2289
|
.innerRadius(d => Math.sqrt(d.y0))
|
|
2264
|
-
.outerRadius(d => Math.sqrt(d.y1))
|
|
2290
|
+
.outerRadius(d => Math.sqrt(d.y1))
|
|
2291
|
+
.cornerRadius(3);
|
|
2265
2292
|
const tooltip = d3.select('body').append('div')
|
|
2266
2293
|
.attr('class', styles$1.tooltip)
|
|
2267
2294
|
.style('opacity', 0)
|
|
@@ -2280,11 +2307,20 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2280
2307
|
.attr('stroke', 'var(--bg-primary)')
|
|
2281
2308
|
.attr('stroke-width', 2)
|
|
2282
2309
|
.style('cursor', 'pointer')
|
|
2310
|
+
.style('filter', 'drop-shadow(0 1px 3px rgba(0,0,0,0.12))')
|
|
2283
2311
|
.on('mouseover', function (event, d) {
|
|
2312
|
+
const hoverArc = d3.arc()
|
|
2313
|
+
.startAngle(d => d.x0)
|
|
2314
|
+
.endAngle(d => d.x1)
|
|
2315
|
+
.innerRadius(d => Math.sqrt(d.y0) - 2)
|
|
2316
|
+
.outerRadius(d => Math.sqrt(d.y1) + 4)
|
|
2317
|
+
.cornerRadius(3);
|
|
2284
2318
|
d3.select(this)
|
|
2285
2319
|
.transition()
|
|
2286
|
-
.duration(
|
|
2287
|
-
.
|
|
2320
|
+
.duration(150)
|
|
2321
|
+
.attr('d', d => hoverArc(d))
|
|
2322
|
+
.style('filter', 'drop-shadow(0 2px 8px rgba(0,0,0,0.2))')
|
|
2323
|
+
.style('opacity', 0.9);
|
|
2288
2324
|
tooltip.transition()
|
|
2289
2325
|
.duration(200)
|
|
2290
2326
|
.style('opacity', 1);
|
|
@@ -2298,10 +2334,12 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2298
2334
|
.style('left', (event.pageX + 10) + 'px')
|
|
2299
2335
|
.style('top', (event.pageY - 28) + 'px');
|
|
2300
2336
|
})
|
|
2301
|
-
.on('mouseout', function () {
|
|
2337
|
+
.on('mouseout', function (event, d) {
|
|
2302
2338
|
d3.select(this)
|
|
2303
2339
|
.transition()
|
|
2304
|
-
.duration(
|
|
2340
|
+
.duration(150)
|
|
2341
|
+
.attr('d', d => arc(d))
|
|
2342
|
+
.style('filter', 'drop-shadow(0 1px 3px rgba(0,0,0,0.12))')
|
|
2305
2343
|
.style('opacity', 1);
|
|
2306
2344
|
tooltip.transition()
|
|
2307
2345
|
.duration(500)
|
|
@@ -2311,9 +2349,32 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2311
2349
|
const angle = d.x1 - d.x0;
|
|
2312
2350
|
return angle > 0.15 && d.depth <= 2;
|
|
2313
2351
|
};
|
|
2314
|
-
|
|
2352
|
+
// Calculate average background color for center text contrast
|
|
2353
|
+
const allSegments = nodes.filter(d => d.depth === 1);
|
|
2354
|
+
const avgColor = allSegments.length > 0 ? d3.interpolateRgb.gamma(2.2)(...allSegments.map(d => getColor(d.data.name, 1)))(0.5) : '#ffffff';
|
|
2355
|
+
const centerTextColor = getTextColor$1(avgColor);
|
|
2356
|
+
// Add center text
|
|
2357
|
+
g.append('text')
|
|
2358
|
+
.attr('text-anchor', 'middle')
|
|
2359
|
+
.attr('alignment-baseline', 'middle')
|
|
2360
|
+
.attr('font-size', '18px')
|
|
2361
|
+
.attr('font-weight', 'bold')
|
|
2362
|
+
.attr('fill', centerTextColor)
|
|
2363
|
+
.style('text-shadow', centerTextColor === '#ffffff' ? '0 1px 3px rgba(0,0,0,0.5)' : '0 1px 3px rgba(255,255,255,0.5)')
|
|
2364
|
+
.text(centerLabel || data.name || 'Total');
|
|
2365
|
+
g.append('text')
|
|
2366
|
+
.attr('text-anchor', 'middle')
|
|
2367
|
+
.attr('alignment-baseline', 'middle')
|
|
2368
|
+
.attr('y', 20)
|
|
2369
|
+
.attr('font-size', '14px')
|
|
2370
|
+
.attr('font-weight', '500')
|
|
2371
|
+
.attr('fill', centerTextColor)
|
|
2372
|
+
.style('text-shadow', centerTextColor === '#ffffff' ? '0 1px 2px rgba(0,0,0,0.4)' : '0 1px 2px rgba(255,255,255,0.4)')
|
|
2373
|
+
.text(`${(root.value || 0).toLocaleString()} ${unit}`);
|
|
2374
|
+
g.selectAll('text.segment-label')
|
|
2315
2375
|
.data(nodes.filter(d => d.depth > 0 && d.value && d.value > 0 && shouldDisplayLabel(d)))
|
|
2316
2376
|
.enter().append('text')
|
|
2377
|
+
.attr('class', 'segment-label')
|
|
2317
2378
|
.attr('transform', d => {
|
|
2318
2379
|
const angle = (d.x0 + d.x1) / 2;
|
|
2319
2380
|
const radius = (Math.sqrt(d.y0) + Math.sqrt(d.y1)) / 2;
|
|
@@ -2323,11 +2384,32 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2323
2384
|
})
|
|
2324
2385
|
.attr('text-anchor', 'middle')
|
|
2325
2386
|
.attr('alignment-baseline', 'middle')
|
|
2326
|
-
.attr('font-size', '
|
|
2327
|
-
.attr('fill',
|
|
2328
|
-
|
|
2387
|
+
.attr('font-size', d => d.depth === 1 ? '13px' : '11px')
|
|
2388
|
+
.attr('fill', d => {
|
|
2389
|
+
let ancestor = d;
|
|
2390
|
+
while (ancestor.depth > 1 && ancestor.parent) {
|
|
2391
|
+
ancestor = ancestor.parent;
|
|
2392
|
+
}
|
|
2393
|
+
const segmentColor = getColor(ancestor.data.name, d.depth);
|
|
2394
|
+
return getTextColor$1(segmentColor);
|
|
2395
|
+
})
|
|
2396
|
+
.attr('font-weight', '600')
|
|
2329
2397
|
.style('pointer-events', 'none')
|
|
2330
|
-
.text
|
|
2398
|
+
.style('text-shadow', d => {
|
|
2399
|
+
let ancestor = d;
|
|
2400
|
+
while (ancestor.depth > 1 && ancestor.parent) {
|
|
2401
|
+
ancestor = ancestor.parent;
|
|
2402
|
+
}
|
|
2403
|
+
const segmentColor = getColor(ancestor.data.name, d.depth);
|
|
2404
|
+
const textColor = getTextColor$1(segmentColor);
|
|
2405
|
+
// Use contrasting shadow color
|
|
2406
|
+
const shadowColor = textColor === '#ffffff' ? 'rgba(0,0,0,0.5)' : 'rgba(255,255,255,0.5)';
|
|
2407
|
+
return `0 1px 2px ${shadowColor}`;
|
|
2408
|
+
})
|
|
2409
|
+
.text(d => {
|
|
2410
|
+
const maxLength = d.depth === 1 ? 12 : 8;
|
|
2411
|
+
return d.data.name.substring(0, maxLength);
|
|
2412
|
+
});
|
|
2331
2413
|
return () => {
|
|
2332
2414
|
tooltip.remove();
|
|
2333
2415
|
};
|
|
@@ -2338,12 +2420,23 @@ const SunburstChart = ({ data, width = 500, height = 500, title = 'Sunburst Char
|
|
|
2338
2420
|
var styles = {"container":"PieChart-module_container__tXjbe","title":"PieChart-module_title__61o0R","chartContainer":"PieChart-module_chartContainer__uLmOz","chart":"PieChart-module_chart__3nqON","legend":"PieChart-module_legend__rAWgh","legendItem":"PieChart-module_legendItem__Nb031","legendColor":"PieChart-module_legendColor__fLuv9","legendLabel":"PieChart-module_legendLabel__xbjBr","legendValue":"PieChart-module_legendValue__h2WS2","tooltip":"PieChart-module_tooltip__140RU"};
|
|
2339
2421
|
|
|
2340
2422
|
const DEFAULT_COLORS = [
|
|
2341
|
-
'#
|
|
2342
|
-
'#
|
|
2343
|
-
'#
|
|
2344
|
-
'#
|
|
2423
|
+
'#6366f1', '#8b5cf6', '#06b6d4', '#10b981',
|
|
2424
|
+
'#f59e0b', '#ef4444', '#ec4899', '#84cc16',
|
|
2425
|
+
'#f97316', '#3b82f6', '#8b5cf6', '#14b8a6',
|
|
2426
|
+
'#f59e0b', '#ef4444', '#06b6d4', '#10b981'
|
|
2345
2427
|
];
|
|
2346
|
-
|
|
2428
|
+
// Calculate text color based on background luminance for optimal contrast
|
|
2429
|
+
const getTextColor = (backgroundColor) => {
|
|
2430
|
+
const color = d3.color(backgroundColor);
|
|
2431
|
+
if (!color)
|
|
2432
|
+
return '#ffffff';
|
|
2433
|
+
const rgb = color.rgb();
|
|
2434
|
+
// Calculate relative luminance using WCAG formula
|
|
2435
|
+
const luminance = (0.299 * rgb.r + 0.587 * rgb.g + 0.114 * rgb.b) / 255;
|
|
2436
|
+
// Return white text for dark backgrounds, black for light backgrounds
|
|
2437
|
+
return luminance > 0.5 ? '#000000' : '#ffffff';
|
|
2438
|
+
};
|
|
2439
|
+
const PieChart = ({ data, width = 400, height = 400, title = 'Distribution', showLegend = true, unit = 'items', centerLabel }) => {
|
|
2347
2440
|
const svgRef = useRef(null);
|
|
2348
2441
|
const radius = Math.min(width, height) / 2 - 20;
|
|
2349
2442
|
useEffect(() => {
|
|
@@ -2357,8 +2450,9 @@ const PieChart = ({ data, width = 400, height = 400, title = 'Distribution', sho
|
|
|
2357
2450
|
.value(d => d.value)
|
|
2358
2451
|
.sort(null);
|
|
2359
2452
|
const arc = d3.arc()
|
|
2360
|
-
.innerRadius(0)
|
|
2361
|
-
.outerRadius(radius)
|
|
2453
|
+
.innerRadius(radius * 0.4)
|
|
2454
|
+
.outerRadius(radius)
|
|
2455
|
+
.cornerRadius(4);
|
|
2362
2456
|
const labelArc = d3.arc()
|
|
2363
2457
|
.innerRadius(radius * 0.7)
|
|
2364
2458
|
.outerRadius(radius * 0.7);
|
|
@@ -2376,13 +2470,19 @@ const PieChart = ({ data, width = 400, height = 400, title = 'Distribution', sho
|
|
|
2376
2470
|
.attr('d', d => arc(d))
|
|
2377
2471
|
.attr('fill', (d, i) => d.data.color || DEFAULT_COLORS[i % DEFAULT_COLORS.length])
|
|
2378
2472
|
.attr('stroke', 'var(--bg-primary)')
|
|
2379
|
-
.attr('stroke-width',
|
|
2473
|
+
.attr('stroke-width', 3)
|
|
2380
2474
|
.style('cursor', 'pointer')
|
|
2475
|
+
.style('filter', 'drop-shadow(0 2px 8px rgba(0,0,0,0.15))')
|
|
2381
2476
|
.on('mouseover', function (event, d) {
|
|
2477
|
+
const hoverArc = d3.arc()
|
|
2478
|
+
.innerRadius(radius * 0.4)
|
|
2479
|
+
.outerRadius(radius * 1.05)
|
|
2480
|
+
.cornerRadius(4);
|
|
2382
2481
|
d3.select(this)
|
|
2383
2482
|
.transition()
|
|
2384
2483
|
.duration(200)
|
|
2385
|
-
.
|
|
2484
|
+
.attr('d', d => hoverArc(d))
|
|
2485
|
+
.style('filter', 'drop-shadow(0 4px 12px rgba(0,0,0,0.25))');
|
|
2386
2486
|
tooltip.transition()
|
|
2387
2487
|
.duration(200)
|
|
2388
2488
|
.style('opacity', 1);
|
|
@@ -2395,27 +2495,59 @@ const PieChart = ({ data, width = 400, height = 400, title = 'Distribution', sho
|
|
|
2395
2495
|
.style('left', (event.pageX + 10) + 'px')
|
|
2396
2496
|
.style('top', (event.pageY - 28) + 'px');
|
|
2397
2497
|
})
|
|
2398
|
-
.on('mouseout', function () {
|
|
2498
|
+
.on('mouseout', function (event, d) {
|
|
2399
2499
|
d3.select(this)
|
|
2400
2500
|
.transition()
|
|
2401
2501
|
.duration(200)
|
|
2402
|
-
.
|
|
2502
|
+
.attr('d', d => arc(d))
|
|
2503
|
+
.style('filter', 'drop-shadow(0 2px 8px rgba(0,0,0,0.15))');
|
|
2403
2504
|
tooltip.transition()
|
|
2404
2505
|
.duration(500)
|
|
2405
2506
|
.style('opacity', 0);
|
|
2406
2507
|
});
|
|
2407
|
-
|
|
2508
|
+
// Calculate average background color for center text contrast
|
|
2509
|
+
const avgColor = data.length > 0 ? d3.interpolateRgb.gamma(2.2)(...data.map((d, i) => d.color || DEFAULT_COLORS[i % DEFAULT_COLORS.length]))(0.5) : '#ffffff';
|
|
2510
|
+
const centerTextColor = getTextColor(avgColor);
|
|
2511
|
+
// Add center text for donut
|
|
2512
|
+
g.append('text')
|
|
2513
|
+
.attr('text-anchor', 'middle')
|
|
2514
|
+
.attr('alignment-baseline', 'middle')
|
|
2515
|
+
.attr('font-size', '20px')
|
|
2516
|
+
.attr('font-weight', 'bold')
|
|
2517
|
+
.attr('fill', centerTextColor)
|
|
2518
|
+
.style('text-shadow', centerTextColor === '#ffffff' ? '0 1px 3px rgba(0,0,0,0.5)' : '0 1px 3px rgba(255,255,255,0.5)')
|
|
2519
|
+
.text(centerLabel || 'Total');
|
|
2520
|
+
g.append('text')
|
|
2521
|
+
.attr('text-anchor', 'middle')
|
|
2522
|
+
.attr('alignment-baseline', 'middle')
|
|
2523
|
+
.attr('y', 22)
|
|
2524
|
+
.attr('font-size', '16px')
|
|
2525
|
+
.attr('font-weight', '600')
|
|
2526
|
+
.attr('fill', centerTextColor)
|
|
2527
|
+
.style('text-shadow', centerTextColor === '#ffffff' ? '0 1px 2px rgba(0,0,0,0.4)' : '0 1px 2px rgba(255,255,255,0.4)')
|
|
2528
|
+
.text(`${total.toLocaleString()} ${unit}`);
|
|
2529
|
+
arcs.filter(d => (d.endAngle - d.startAngle) > 0.2)
|
|
2408
2530
|
.append('text')
|
|
2409
2531
|
.attr('transform', d => `translate(${labelArc.centroid(d)})`)
|
|
2410
2532
|
.attr('text-anchor', 'middle')
|
|
2411
2533
|
.attr('alignment-baseline', 'middle')
|
|
2412
|
-
.attr('font-size', '
|
|
2413
|
-
.attr('fill',
|
|
2414
|
-
.
|
|
2534
|
+
.attr('font-size', '13px')
|
|
2535
|
+
.attr('fill', (d, i) => {
|
|
2536
|
+
const segmentColor = d.data.color || DEFAULT_COLORS[i % DEFAULT_COLORS.length];
|
|
2537
|
+
return getTextColor(segmentColor);
|
|
2538
|
+
})
|
|
2539
|
+
.attr('font-weight', '600')
|
|
2415
2540
|
.style('pointer-events', 'none')
|
|
2541
|
+
.style('text-shadow', (d, i) => {
|
|
2542
|
+
const segmentColor = d.data.color || DEFAULT_COLORS[i % DEFAULT_COLORS.length];
|
|
2543
|
+
const textColor = getTextColor(segmentColor);
|
|
2544
|
+
// Use contrasting shadow color
|
|
2545
|
+
const shadowColor = textColor === '#ffffff' ? 'rgba(0,0,0,0.4)' : 'rgba(255,255,255,0.4)';
|
|
2546
|
+
return `0 1px 2px ${shadowColor}`;
|
|
2547
|
+
})
|
|
2416
2548
|
.text(d => {
|
|
2417
2549
|
const percentage = ((d.data.value / total) * 100);
|
|
2418
|
-
return percentage >
|
|
2550
|
+
return percentage > 8 ? `${percentage.toFixed(0)}%` : '';
|
|
2419
2551
|
});
|
|
2420
2552
|
return () => {
|
|
2421
2553
|
tooltip.remove();
|