uibee 2.15.0 → 2.16.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.
@@ -26,3 +26,5 @@ export { default as Table } from './table/table';
26
26
  export { default as Pagination } from './table/pagination';
27
27
  export { default as MarkdownRender } from './markdownrender/markdownRender';
28
28
  export { default as ConfirmPopup } from './confirm/confirmPopup';
29
+ export { default as SeverityPill } from './vulnerability/severityPill';
30
+ export { default as Toggle } from './layout/toggle';
@@ -38,3 +38,7 @@ export { default as Pagination } from './table/pagination';
38
38
  export { default as MarkdownRender } from './markdownrender/markdownRender';
39
39
  // Confirm
40
40
  export { default as ConfirmPopup } from './confirm/confirmPopup';
41
+ // Vulnerability
42
+ export { default as SeverityPill } from './vulnerability/severityPill';
43
+ // Layout
44
+ export { default as Toggle } from './layout/toggle';
@@ -0,0 +1,14 @@
1
+ type ToggleOption<T> = {
2
+ value: T;
3
+ label?: string;
4
+ text?: string;
5
+ icon?: React.ReactNode;
6
+ };
7
+ type ToggleProps<T> = {
8
+ value: T;
9
+ onChange: (value: T) => void;
10
+ left: ToggleOption<T>;
11
+ right: ToggleOption<T>;
12
+ };
13
+ export default function Toggle<T>({ value, onChange, left, right, }: ToggleProps<T>): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
+ export default function Toggle({ value, onChange, left, right, }) {
3
+ const active = 'bg-login-200 text-login-950 shadow';
4
+ const idle = 'text-login-200 hover:bg-login-50/10 hover:text-login-50';
5
+ const base = 'flex items-center justify-center rounded-full transition gap-1';
6
+ function renderContent(opt) {
7
+ return (_jsxs(_Fragment, { children: [opt.icon, opt.text && _jsx("span", { children: opt.text })] }));
8
+ }
9
+ const isLeftActive = value === left.value;
10
+ const isRightActive = value === right.value;
11
+ return (_jsxs("div", { className: 'flex items-center rounded-full border border-login-100/10 bg-login-50/5 p-1', children: [_jsx("button", { type: 'button', onClick: () => onChange(left.value), "aria-label": left.label ?? left.text, "aria-pressed": isLeftActive, className: `${base} px-2 h-7 ${isLeftActive ? active : idle}`, children: renderContent(left) }), _jsx("button", { type: 'button', onClick: () => onChange(right.value), "aria-label": right.label ?? right.text, "aria-pressed": isRightActive, className: `${base} px-2 h-7 ${isRightActive ? active : idle}`, children: renderContent(right) })] }));
12
+ }
@@ -0,0 +1,4 @@
1
+ type SeverityLevel = 'critical' | 'high' | 'medium' | 'low' | 'unknown';
2
+ export declare const severityLabel: Record<SeverityLevel, string>;
3
+ export declare const severityClasses: Record<SeverityLevel, string>;
4
+ export {};
@@ -0,0 +1,14 @@
1
+ export const severityLabel = {
2
+ critical: 'Critical',
3
+ high: 'High',
4
+ medium: 'Medium',
5
+ low: 'Low',
6
+ unknown: 'Unknown',
7
+ };
8
+ export const severityClasses = {
9
+ critical: 'border-red-400/25 bg-red-500/10 text-red-200',
10
+ high: 'border-orange-400/25 bg-orange-500/10 text-orange-200',
11
+ medium: 'border-amber-400/25 bg-amber-500/10 text-amber-200',
12
+ low: 'border-sky-400/25 bg-sky-500/10 text-sky-200',
13
+ unknown: 'border-login-100/10 bg-login-50/5 text-login-200',
14
+ };
@@ -0,0 +1,8 @@
1
+ type SeverityLevel = 'critical' | 'high' | 'medium' | 'low' | 'unknown';
2
+ type SeverityPillProps = {
3
+ severity: SeverityLevel;
4
+ count: number;
5
+ compact?: boolean;
6
+ };
7
+ export default function SeverityPill({ severity, count, compact }: SeverityPillProps): import("react/jsx-runtime").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { severityClasses, severityLabel } from './constants';
3
+ export default function SeverityPill({ severity, count, compact = false }) {
4
+ if (count === 0) {
5
+ return null;
6
+ }
7
+ return (_jsxs("div", { className: `rounded-xl border ${compact ? 'px-3 py-2' : 'p-3'} ${severityClasses[severity]}`, children: [_jsx("div", { className: 'text-[11px] font-medium uppercase tracking-[0.18em]', children: severityLabel[severity] }), _jsx("div", { className: `${compact ? 'mt-1 text-sm' : 'mt-2 text-lg'} font-semibold`, children: count })] }));
8
+ }
@@ -1,4 +1,4 @@
1
- /*! tailwindcss v4.2.1 | MIT License | https://tailwindcss.com */
1
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
2
  @layer properties;
3
3
  @layer theme, base, components, utilities;
4
4
  @layer theme {
@@ -13,12 +13,21 @@
13
13
  --color-red-600: oklch(57.7% 0.245 27.325);
14
14
  --color-red-700: oklch(50.5% 0.213 27.518);
15
15
  --color-red-900: oklch(39.6% 0.141 25.723);
16
+ --color-orange-200: oklch(90.1% 0.076 70.697);
17
+ --color-orange-400: oklch(75% 0.183 55.934);
18
+ --color-orange-500: oklch(70.5% 0.213 47.604);
19
+ --color-amber-200: oklch(92.4% 0.12 95.746);
20
+ --color-amber-400: oklch(82.8% 0.189 84.429);
21
+ --color-amber-500: oklch(76.9% 0.188 70.08);
16
22
  --color-yellow-400: oklch(85.2% 0.199 91.936);
17
23
  --color-yellow-500: oklch(79.5% 0.184 86.047);
18
24
  --color-yellow-600: oklch(68.1% 0.162 75.834);
19
25
  --color-green-400: oklch(79.2% 0.209 151.711);
20
26
  --color-green-500: oklch(72.3% 0.219 149.579);
21
27
  --color-green-600: oklch(62.7% 0.194 149.214);
28
+ --color-sky-200: oklch(90.1% 0.058 230.902);
29
+ --color-sky-400: oklch(74.6% 0.16 232.661);
30
+ --color-sky-500: oklch(68.5% 0.169 237.323);
22
31
  --color-blue-400: oklch(70.7% 0.165 254.624);
23
32
  --color-blue-500: oklch(62.3% 0.214 259.815);
24
33
  --color-blue-600: oklch(54.6% 0.245 262.881);
@@ -71,6 +80,7 @@
71
80
  --default-font-family: var(--font-sans);
72
81
  --default-mono-font-family: var(--font-mono);
73
82
  --color-login: #fd8738;
83
+ --color-login-950: #0e0e0e;
74
84
  --color-login-900: #121212;
75
85
  --color-login-800: #181818;
76
86
  --color-login-700: #1a1a1a;
@@ -1119,6 +1129,9 @@
1119
1129
  .h-6 {
1120
1130
  height: calc(var(--spacing) * 6);
1121
1131
  }
1132
+ .h-7 {
1133
+ height: calc(var(--spacing) * 7);
1134
+ }
1122
1135
  .h-8 {
1123
1136
  height: calc(var(--spacing) * 8);
1124
1137
  }
@@ -1509,12 +1522,24 @@
1509
1522
  --tw-border-style: none;
1510
1523
  border-style: none;
1511
1524
  }
1525
+ .border-amber-400\/25 {
1526
+ border-color: color-mix(in srgb, oklch(82.8% 0.189 84.429) 25%, transparent);
1527
+ @supports (color: color-mix(in lab, red, red)) {
1528
+ border-color: color-mix(in oklab, var(--color-amber-400) 25%, transparent);
1529
+ }
1530
+ }
1512
1531
  .border-gray-200 {
1513
1532
  border-color: var(--color-gray-200);
1514
1533
  }
1515
1534
  .border-login-50 {
1516
1535
  border-color: var(--color-login-50);
1517
1536
  }
1537
+ .border-login-100\/10 {
1538
+ border-color: color-mix(in srgb, #b0b0b0 10%, transparent);
1539
+ @supports (color: color-mix(in lab, red, red)) {
1540
+ border-color: color-mix(in oklab, var(--color-login-100) 10%, transparent);
1541
+ }
1542
+ }
1518
1543
  .border-login-200 {
1519
1544
  border-color: var(--color-login-200);
1520
1545
  }
@@ -1539,9 +1564,27 @@
1539
1564
  border-color: color-mix(in oklab, var(--color-login-600) 50%, transparent);
1540
1565
  }
1541
1566
  }
1567
+ .border-orange-400\/25 {
1568
+ border-color: color-mix(in srgb, oklch(75% 0.183 55.934) 25%, transparent);
1569
+ @supports (color: color-mix(in lab, red, red)) {
1570
+ border-color: color-mix(in oklab, var(--color-orange-400) 25%, transparent);
1571
+ }
1572
+ }
1573
+ .border-red-400\/25 {
1574
+ border-color: color-mix(in srgb, oklch(70.4% 0.191 22.216) 25%, transparent);
1575
+ @supports (color: color-mix(in lab, red, red)) {
1576
+ border-color: color-mix(in oklab, var(--color-red-400) 25%, transparent);
1577
+ }
1578
+ }
1542
1579
  .border-red-500 {
1543
1580
  border-color: var(--color-red-500);
1544
1581
  }
1582
+ .border-sky-400\/25 {
1583
+ border-color: color-mix(in srgb, oklch(74.6% 0.16 232.661) 25%, transparent);
1584
+ @supports (color: color-mix(in lab, red, red)) {
1585
+ border-color: color-mix(in oklab, var(--color-sky-400) 25%, transparent);
1586
+ }
1587
+ }
1545
1588
  .border-white {
1546
1589
  border-color: var(--color-white);
1547
1590
  }
@@ -1551,6 +1594,12 @@
1551
1594
  .bg-\[\#18181899\] {
1552
1595
  background-color: #18181899;
1553
1596
  }
1597
+ .bg-amber-500\/10 {
1598
+ background-color: color-mix(in srgb, oklch(76.9% 0.188 70.08) 10%, transparent);
1599
+ @supports (color: color-mix(in lab, red, red)) {
1600
+ background-color: color-mix(in oklab, var(--color-amber-500) 10%, transparent);
1601
+ }
1602
+ }
1554
1603
  .bg-black\/60 {
1555
1604
  background-color: color-mix(in srgb, #000 60%, transparent);
1556
1605
  @supports (color: color-mix(in lab, red, red)) {
@@ -1614,6 +1663,9 @@
1614
1663
  background-color: color-mix(in oklab, var(--color-login-50) 5%, transparent);
1615
1664
  }
1616
1665
  }
1666
+ .bg-login-200 {
1667
+ background-color: var(--color-login-200);
1668
+ }
1617
1669
  .bg-login-400 {
1618
1670
  background-color: var(--color-login-400);
1619
1671
  }
@@ -1668,6 +1720,18 @@
1668
1720
  background-color: color-mix(in oklab, var(--color-login) 70%, transparent);
1669
1721
  }
1670
1722
  }
1723
+ .bg-orange-500\/10 {
1724
+ background-color: color-mix(in srgb, oklch(70.5% 0.213 47.604) 10%, transparent);
1725
+ @supports (color: color-mix(in lab, red, red)) {
1726
+ background-color: color-mix(in oklab, var(--color-orange-500) 10%, transparent);
1727
+ }
1728
+ }
1729
+ .bg-red-500\/10 {
1730
+ background-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 10%, transparent);
1731
+ @supports (color: color-mix(in lab, red, red)) {
1732
+ background-color: color-mix(in oklab, var(--color-red-500) 10%, transparent);
1733
+ }
1734
+ }
1671
1735
  .bg-red-500\/20 {
1672
1736
  background-color: color-mix(in srgb, oklch(63.7% 0.237 25.331) 20%, transparent);
1673
1737
  @supports (color: color-mix(in lab, red, red)) {
@@ -1689,6 +1753,12 @@
1689
1753
  .bg-red-900 {
1690
1754
  background-color: var(--color-red-900);
1691
1755
  }
1756
+ .bg-sky-500\/10 {
1757
+ background-color: color-mix(in srgb, oklch(68.5% 0.169 237.323) 10%, transparent);
1758
+ @supports (color: color-mix(in lab, red, red)) {
1759
+ background-color: color-mix(in oklab, var(--color-sky-500) 10%, transparent);
1760
+ }
1761
+ }
1692
1762
  .bg-transparent {
1693
1763
  background-color: transparent;
1694
1764
  }
@@ -1931,6 +2001,9 @@
1931
2001
  font-size: var(--text-xs);
1932
2002
  line-height: var(--tw-leading, var(--text-xs--line-height));
1933
2003
  }
2004
+ .text-\[11px\] {
2005
+ font-size: 11px;
2006
+ }
1934
2007
  .leading-4 {
1935
2008
  --tw-leading: calc(var(--spacing) * 4);
1936
2009
  line-height: calc(var(--spacing) * 4);
@@ -1975,6 +2048,10 @@
1975
2048
  --tw-tracking: 0.05em;
1976
2049
  letter-spacing: 0.05em;
1977
2050
  }
2051
+ .tracking-\[0\.18em\] {
2052
+ --tw-tracking: 0.18em;
2053
+ letter-spacing: 0.18em;
2054
+ }
1978
2055
  .tracking-tight {
1979
2056
  --tw-tracking: var(--tracking-tight);
1980
2057
  letter-spacing: var(--tracking-tight);
@@ -1986,6 +2063,9 @@
1986
2063
  .whitespace-nowrap {
1987
2064
  white-space: nowrap;
1988
2065
  }
2066
+ .text-amber-200 {
2067
+ color: var(--color-amber-200);
2068
+ }
1989
2069
  .text-blue-400 {
1990
2070
  color: var(--color-blue-400);
1991
2071
  }
@@ -2022,18 +2102,30 @@
2022
2102
  .text-login-800 {
2023
2103
  color: var(--color-login-800);
2024
2104
  }
2105
+ .text-login-950 {
2106
+ color: var(--color-login-950);
2107
+ }
2025
2108
  .text-login-text {
2026
2109
  color: var(--color-login-text);
2027
2110
  }
2028
2111
  .text-login-text\! {
2029
2112
  color: var(--color-login-text) !important;
2030
2113
  }
2114
+ .text-orange-200 {
2115
+ color: var(--color-orange-200);
2116
+ }
2117
+ .text-red-200 {
2118
+ color: var(--color-red-200);
2119
+ }
2031
2120
  .text-red-400 {
2032
2121
  color: var(--color-red-400);
2033
2122
  }
2034
2123
  .text-red-500 {
2035
2124
  color: var(--color-red-500);
2036
2125
  }
2126
+ .text-sky-200 {
2127
+ color: var(--color-sky-200);
2128
+ }
2037
2129
  .text-white {
2038
2130
  color: var(--color-white);
2039
2131
  }
@@ -2497,6 +2589,16 @@
2497
2589
  }
2498
2590
  }
2499
2591
  }
2592
+ .hover\:bg-login-50\/10 {
2593
+ &:hover {
2594
+ @media (hover: hover) {
2595
+ background-color: color-mix(in srgb, #ededed 10%, transparent);
2596
+ @supports (color: color-mix(in lab, red, red)) {
2597
+ background-color: color-mix(in oklab, var(--color-login-50) 10%, transparent);
2598
+ }
2599
+ }
2600
+ }
2601
+ }
2500
2602
  .hover\:bg-login-300\/20 {
2501
2603
  &:hover {
2502
2604
  @media (hover: hover) {
@@ -2622,6 +2724,13 @@
2622
2724
  }
2623
2725
  }
2624
2726
  }
2727
+ .hover\:text-login-50 {
2728
+ &:hover {
2729
+ @media (hover: hover) {
2730
+ color: var(--color-login-50);
2731
+ }
2732
+ }
2733
+ }
2625
2734
  .hover\:text-login-100 {
2626
2735
  &:hover {
2627
2736
  @media (hover: hover) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uibee",
3
- "version": "2.15.0",
3
+ "version": "2.16.0",
4
4
  "description": "Shared components, functions and hooks for reuse across Login projects",
5
5
  "homepage": "https://github.com/Login-Linjeforening-for-IT/uibee#readme",
6
6
  "bugs": {
@@ -24,7 +24,7 @@
24
24
  },
25
25
  "scripts": {
26
26
  "build:clean": "rm -rf dist",
27
- "build:css": "node --loader ts-node/esm src/scripts/buildCss.ts",
27
+ "build:css": "node src/scripts/buildCss.ts",
28
28
  "build:rewrite": "node dist/src/scripts/rewriteAlias.js",
29
29
  "build:ts": "tsc --declaration",
30
30
  "build": "npm run build:clean && npm run build:css && npm run build:ts && npm run build:rewrite",
@@ -32,27 +32,27 @@
32
32
  "lint:fix": "eslint --fix ./src"
33
33
  },
34
34
  "peerDependencies": {
35
- "next": "^16.1.6",
35
+ "next": "^16.2.1",
36
36
  "react": "^19.2.4"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@stylistic/eslint-plugin": "^5.10.0",
40
- "@tailwindcss/postcss": "^4.2.1",
40
+ "@tailwindcss/postcss": "^4.2.2",
41
41
  "@tailwindcss/typography": "^0.5.19",
42
- "@types/node": "^25.5.0",
42
+ "@types/node": "^25.6.0",
43
43
  "@types/react": "19.2.14",
44
44
  "@types/react-dom": "^19.2.3",
45
- "eslint": "^10.0.3",
45
+ "eslint": "^10.2.0",
46
46
  "glob": "^13.0.6",
47
- "postcss": "^8.5.8",
48
- "tailwindcss": "^4.2.1",
47
+ "postcss": "^8.5.10",
48
+ "tailwindcss": "^4.2.2",
49
49
  "ts-node": "^10.9.2",
50
- "typescript": "^5.9.3",
51
- "typescript-eslint": "^8.57.0"
50
+ "typescript": "^6.0.2",
51
+ "typescript-eslint": "^8.58.2"
52
52
  },
53
53
  "dependencies": {
54
- "lucide-react": "^0.577.0",
55
- "react-dom": "19.2.4",
54
+ "lucide-react": "^1.8.0",
55
+ "react-dom": "19.2.5",
56
56
  "react-markdown": "^10.1.0",
57
57
  "remark-gfm": "^4.0.1",
58
58
  "utilbee": "^1.4.1"
@@ -48,4 +48,10 @@ export { default as Pagination } from './table/pagination'
48
48
  export { default as MarkdownRender } from './markdownrender/markdownRender'
49
49
 
50
50
  // Confirm
51
- export { default as ConfirmPopup } from './confirm/confirmPopup'
51
+ export { default as ConfirmPopup } from './confirm/confirmPopup'
52
+
53
+ // Vulnerability
54
+ export { default as SeverityPill } from './vulnerability/severityPill'
55
+
56
+ // Layout
57
+ export { default as Toggle } from './layout/toggle'
@@ -0,0 +1,62 @@
1
+ type ToggleOption<T> = {
2
+ value: T
3
+ label?: string
4
+ text?: string
5
+ icon?: React.ReactNode
6
+ }
7
+
8
+ type ToggleProps<T> = {
9
+ value: T
10
+ onChange: (value: T) => void
11
+ left: ToggleOption<T>
12
+ right: ToggleOption<T>
13
+ }
14
+
15
+ export default function Toggle<T>({
16
+ value,
17
+ onChange,
18
+ left,
19
+ right,
20
+ }: ToggleProps<T>) {
21
+ const active = 'bg-login-200 text-login-950 shadow'
22
+ const idle = 'text-login-200 hover:bg-login-50/10 hover:text-login-50'
23
+
24
+ const base =
25
+ 'flex items-center justify-center rounded-full transition gap-1'
26
+
27
+ function renderContent(opt: ToggleOption<T>) {
28
+ return (
29
+ <>
30
+ {opt.icon}
31
+ {opt.text && <span>{opt.text}</span>}
32
+ </>
33
+ )
34
+ }
35
+
36
+ const isLeftActive = value === left.value
37
+ const isRightActive = value === right.value
38
+
39
+ return (
40
+ <div className='flex items-center rounded-full border border-login-100/10 bg-login-50/5 p-1'>
41
+ <button
42
+ type='button'
43
+ onClick={() => onChange(left.value)}
44
+ aria-label={left.label ?? left.text}
45
+ aria-pressed={isLeftActive}
46
+ className={`${base} px-2 h-7 ${isLeftActive ? active : idle}`}
47
+ >
48
+ {renderContent(left)}
49
+ </button>
50
+
51
+ <button
52
+ type='button'
53
+ onClick={() => onChange(right.value)}
54
+ aria-label={right.label ?? right.text}
55
+ aria-pressed={isRightActive}
56
+ className={`${base} px-2 h-7 ${isRightActive ? active : idle}`}
57
+ >
58
+ {renderContent(right)}
59
+ </button>
60
+ </div>
61
+ )
62
+ }
@@ -0,0 +1,17 @@
1
+ type SeverityLevel = 'critical' | 'high' | 'medium' | 'low' | 'unknown'
2
+
3
+ export const severityLabel: Record<SeverityLevel, string> = {
4
+ critical: 'Critical',
5
+ high: 'High',
6
+ medium: 'Medium',
7
+ low: 'Low',
8
+ unknown: 'Unknown',
9
+ }
10
+
11
+ export const severityClasses: Record<SeverityLevel, string> = {
12
+ critical: 'border-red-400/25 bg-red-500/10 text-red-200',
13
+ high: 'border-orange-400/25 bg-orange-500/10 text-orange-200',
14
+ medium: 'border-amber-400/25 bg-amber-500/10 text-amber-200',
15
+ low: 'border-sky-400/25 bg-sky-500/10 text-sky-200',
16
+ unknown: 'border-login-100/10 bg-login-50/5 text-login-200',
17
+ }
@@ -0,0 +1,22 @@
1
+ import { severityClasses, severityLabel } from './constants'
2
+
3
+ type SeverityLevel = 'critical' | 'high' | 'medium' | 'low' | 'unknown'
4
+
5
+ type SeverityPillProps = {
6
+ severity: SeverityLevel
7
+ count: number
8
+ compact?: boolean
9
+ }
10
+
11
+ export default function SeverityPill({ severity, count, compact = false }: SeverityPillProps) {
12
+ if (count === 0) {
13
+ return null
14
+ }
15
+
16
+ return (
17
+ <div className={`rounded-xl border ${compact ? 'px-3 py-2' : 'p-3'} ${severityClasses[severity]}`}>
18
+ <div className='text-[11px] font-medium uppercase tracking-[0.18em]'>{severityLabel[severity]}</div>
19
+ <div className={`${compact ? 'mt-1 text-sm' : 'mt-2 text-lg'} font-semibold`}>{count}</div>
20
+ </div>
21
+ )
22
+ }
package/tsconfig.json CHANGED
@@ -8,6 +8,7 @@
8
8
  "rootDir": ".",
9
9
  "esModuleInterop": true,
10
10
  "forceConsistentCasingInFileNames": true,
11
+ "noUncheckedSideEffectImports": false,
11
12
  "strict": true,
12
13
  "skipLibCheck": true,
13
14
  "jsx": "react-jsx",