@stisocial/ui 0.2.0 → 0.2.1

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.
Files changed (42) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/components/TimeSlotPicker/TimeSlotPicker.d.ts +1 -11
  3. package/dist/components/TimeSlotPicker/TimeSlotPicker.js +2 -24
  4. package/dist/components/TimeSlotPicker/index.d.ts +3 -2
  5. package/dist/components/TimeSlotPicker/timeSlots.d.ts +12 -0
  6. package/dist/components/TimeSlotPicker/timeSlots.js +25 -0
  7. package/dist/id/AccountMenu/AccountMenu.css +128 -44
  8. package/dist/id/AccountMenu/AccountMenu.d.ts +37 -9
  9. package/dist/id/AccountMenu/AccountMenu.js +138 -65
  10. package/dist/id/AccountMenu/AccountMenu.module.js +16 -9
  11. package/dist/id/AccountMenu/index.d.ts +2 -2
  12. package/dist/id/AppSwitcher/AppSwitcher.css +153 -31
  13. package/dist/id/AppSwitcher/AppSwitcher.d.ts +31 -6
  14. package/dist/id/AppSwitcher/AppSwitcher.js +90 -37
  15. package/dist/id/AppSwitcher/AppSwitcher.module.js +12 -6
  16. package/dist/id/AppSwitcher/index.d.ts +2 -2
  17. package/dist/id/OrgSwitcher/OrgSwitcher.css +129 -17
  18. package/dist/id/OrgSwitcher/OrgSwitcher.d.ts +30 -5
  19. package/dist/id/OrgSwitcher/OrgSwitcher.js +110 -74
  20. package/dist/id/OrgSwitcher/OrgSwitcher.module.js +11 -7
  21. package/dist/id/OrgSwitcher/index.d.ts +2 -2
  22. package/dist/id/PermissionGate/PermissionGate.css +25 -14
  23. package/dist/id/PermissionGate/PermissionGate.d.ts +3 -1
  24. package/dist/id/PermissionGate/PermissionGate.js +15 -8
  25. package/dist/id/PermissionGate/PermissionGate.module.js +6 -5
  26. package/dist/id/SignInButton/SignInButton.css +179 -0
  27. package/dist/id/SignInButton/SignInButton.d.ts +12 -3
  28. package/dist/id/SignInButton/SignInButton.js +37 -18
  29. package/dist/id/SignInButton/SignInButton.module.js +10 -0
  30. package/dist/id/_internal/StiMark/StiMark.css +28 -0
  31. package/dist/id/_internal/StiMark/StiMark.js +37 -0
  32. package/dist/id/_internal/StiMark/StiMark.module.js +8 -0
  33. package/dist/id/index.d.ts +4 -4
  34. package/dist/id/index.js +4 -4
  35. package/dist/index.d.ts +3 -2
  36. package/dist/index.js +2 -1
  37. package/dist/messages/messages.d.ts +7 -0
  38. package/dist/messages/messages.js +14 -0
  39. package/dist/styles.css +644 -106
  40. package/dist/text/text.d.ts +5 -1
  41. package/dist/text/text.js +8 -2
  42. package/package.json +1 -1
@@ -1,9 +1,10 @@
1
1
  @layer sti.reset, sti.tokens, sti.base, sti.components, sti.variants, sti.utilities;
2
2
  @layer sti.components {
3
- .sti-OrgSwitcher-trigger-8cf9a {
3
+ .sti-OrgSwitcher-trigger-0f64d {
4
4
  --sti-org-switcher-h: var(--sti-control-h-md);
5
5
  --sti-org-switcher-bg: transparent;
6
6
  --sti-org-switcher-border: var(--sti-border-control);
7
+ align-self: center;
7
8
  align-items: center;
8
9
  gap: var(--sti-space-2);
9
10
  box-sizing: border-box;
@@ -21,73 +22,180 @@
21
22
  cursor: pointer;
22
23
  transition: background-color var(--sti-duration-fast) var(--sti-ease-snap),
23
24
  border-color var(--sti-duration-fast) var(--sti-ease-snap);
25
+ flex: none;
24
26
  display: inline-flex;
25
27
  }
26
28
 
27
- .sti-OrgSwitcher-trigger-8cf9a[data-size="sm"] {
29
+ .sti-OrgSwitcher-trigger-0f64d[data-size="sm"] {
28
30
  --sti-org-switcher-h: var(--sti-control-h-sm);
29
31
  }
30
32
 
31
- .sti-OrgSwitcher-trigger-8cf9a[data-size="lg"] {
33
+ .sti-OrgSwitcher-trigger-0f64d[data-size="lg"] {
32
34
  --sti-org-switcher-h: var(--sti-control-h-lg);
33
35
  font-size: var(--sti-font-size-md);
34
36
  }
35
37
 
36
38
  @media (pointer: coarse) {
37
- .sti-OrgSwitcher-trigger-8cf9a {
39
+ .sti-OrgSwitcher-trigger-0f64d {
38
40
  min-block-size: 2.75rem;
39
41
  }
40
42
  }
41
43
 
42
44
  @media (hover: hover) {
43
- .sti-OrgSwitcher-trigger-8cf9a[data-hovered]:not([data-disabled]) {
45
+ .sti-OrgSwitcher-trigger-0f64d[data-hovered]:not([data-disabled]) {
44
46
  --sti-org-switcher-border: var(--sti-border-accent);
45
47
  --sti-org-switcher-bg: var(--sti-bg-surface-hover);
46
48
  }
47
49
  }
48
50
 
49
- .sti-OrgSwitcher-trigger-8cf9a[data-pressed] {
51
+ .sti-OrgSwitcher-trigger-0f64d[data-pressed] {
50
52
  --sti-org-switcher-bg: var(--sti-bg-surface-active);
51
53
  }
52
54
 
53
- .sti-OrgSwitcher-trigger-8cf9a[data-focus-visible] {
55
+ .sti-OrgSwitcher-trigger-0f64d[data-focus-visible] {
54
56
  outline: var(--sti-focus-ring-width) solid var(--sti-focus-ring);
55
57
  outline-offset: var(--sti-focus-ring-offset);
56
58
  }
57
59
 
58
- .sti-OrgSwitcher-trigger-8cf9a[data-disabled] {
60
+ .sti-OrgSwitcher-trigger-0f64d[data-disabled] {
59
61
  opacity: var(--sti-opacity-disabled);
60
62
  cursor: not-allowed;
61
63
  }
62
64
 
63
- .sti-OrgSwitcher-name-0b2eb {
65
+ .sti-OrgSwitcher-name-c202c {
64
66
  text-overflow: ellipsis;
65
67
  white-space: nowrap;
66
68
  min-inline-size: 0;
67
69
  overflow: hidden;
68
70
  }
69
71
 
70
- .sti-OrgSwitcher-chevron-e70b6 {
72
+ .sti-OrgSwitcher-mark-a5082 {
73
+ --sti-org-mark-bg: var(--sti-bg-surface-active);
74
+ --sti-org-mark-fg: var(--sti-fg);
75
+ box-sizing: border-box;
76
+ border-radius: var(--sti-radius-sm);
77
+ background: var(--sti-org-mark-bg);
78
+ block-size: 1.5rem;
79
+ inline-size: 1.5rem;
80
+ color: var(--sti-org-mark-fg);
81
+ flex: none;
82
+ place-items: center;
83
+ display: inline-grid;
84
+ }
85
+
86
+ .sti-OrgSwitcher-mark-a5082 > svg {
87
+ block-size: .875rem;
88
+ inline-size: .875rem;
89
+ }
90
+
91
+ .sti-OrgSwitcher-mark-a5082[data-color="neutral-strong"] {
92
+ --sti-org-mark-bg: var(--sti-fill-neutral);
93
+ --sti-org-mark-fg: var(--sti-fg-on-neutral);
94
+ }
95
+
96
+ .sti-OrgSwitcher-mark-a5082[data-color="success"] {
97
+ --sti-org-mark-bg: var(--sti-bg-success-subtle);
98
+ --sti-org-mark-fg: var(--sti-fg-success-strong);
99
+ }
100
+
101
+ .sti-OrgSwitcher-mark-a5082[data-color="success-strong"] {
102
+ --sti-org-mark-bg: var(--sti-fill-success);
103
+ --sti-org-mark-fg: var(--sti-fg-on-success);
104
+ }
105
+
106
+ .sti-OrgSwitcher-mark-a5082[data-color="warning"] {
107
+ --sti-org-mark-bg: var(--sti-bg-warning-subtle);
108
+ --sti-org-mark-fg: var(--sti-fg-warning-strong);
109
+ }
110
+
111
+ .sti-OrgSwitcher-mark-a5082[data-color="warning-strong"] {
112
+ --sti-org-mark-bg: var(--sti-fill-warning);
113
+ --sti-org-mark-fg: var(--sti-fg-on-warning);
114
+ }
115
+
116
+ .sti-OrgSwitcher-chevron-d6eea {
71
117
  color: var(--sti-fg-muted);
72
118
  flex: none;
73
119
  }
74
120
 
75
- .sti-OrgSwitcher-card-297cc {
76
- min-inline-size: 0;
121
+ .sti-OrgSwitcher-card-af900 {
122
+ --sti-floating-w: 20rem;
77
123
  }
78
124
 
79
- .sti-OrgSwitcher-body-e5f5e {
125
+ .sti-OrgSwitcher-body-dd131 {
80
126
  gap: var(--sti-space-2);
81
127
  min-inline-size: 0;
82
128
  display: grid;
83
129
  }
84
130
 
85
- .sti-OrgSwitcher-scroll-eca85 {
131
+ .sti-OrgSwitcher-scroll-045d7 {
86
132
  max-block-size: 18rem;
87
133
  overflow: auto;
88
134
  }
89
135
 
90
- .sti-OrgSwitcher-empty-1d36a {
136
+ .sti-OrgSwitcher-create-8b4bd {
137
+ border-block-start: var(--sti-border-width) solid var(--sti-border-subtle);
138
+ padding-block-start: var(--sti-space-1);
139
+ }
140
+
141
+ .sti-OrgSwitcher-createRow-c2255 {
142
+ align-items: center;
143
+ gap: var(--sti-space-3);
144
+ box-sizing: border-box;
145
+ inline-size: 100%;
146
+ min-block-size: var(--sti-control-h-sm);
147
+ padding-block: var(--sti-space-2);
148
+ padding-inline: var(--sti-space-3);
149
+ border-radius: var(--sti-radius-sm);
150
+ color: var(--sti-fg);
151
+ font-family: var(--sti-font-text);
152
+ font-size: var(--sti-font-size-sm);
153
+ font-weight: var(--sti-font-weight-medium);
154
+ line-height: var(--sti-line-height-sm);
155
+ text-align: start;
156
+ cursor: pointer;
157
+ background: none;
158
+ border: 0;
159
+ margin: 0;
160
+ text-decoration: none;
161
+ display: flex;
162
+ }
163
+
164
+ @media (pointer: coarse) {
165
+ .sti-OrgSwitcher-createRow-c2255 {
166
+ min-block-size: var(--sti-control-h-md);
167
+ }
168
+ }
169
+
170
+ @media (hover: hover) {
171
+ .sti-OrgSwitcher-createRow-c2255[data-hovered] {
172
+ background: var(--sti-bg-surface-hover);
173
+ }
174
+ }
175
+
176
+ .sti-OrgSwitcher-createRow-c2255[data-pressed] {
177
+ background: var(--sti-bg-surface-active);
178
+ }
179
+
180
+ .sti-OrgSwitcher-createRow-c2255[data-focus-visible] {
181
+ outline: var(--sti-focus-ring-width) solid var(--sti-focus-ring);
182
+ outline-offset: calc(var(--sti-focus-ring-width) * -1);
183
+ }
184
+
185
+ .sti-OrgSwitcher-createIcon-a21cc {
186
+ box-sizing: border-box;
187
+ block-size: 1.5rem;
188
+ inline-size: 1.5rem;
189
+ padding: var(--sti-space-1);
190
+ border: var(--sti-border-width) dashed var(--sti-border-strong);
191
+ border-radius: var(--sti-radius-sm);
192
+ color: var(--sti-fg-muted);
193
+ flex: none;
194
+ place-items: center;
195
+ display: inline-grid;
196
+ }
197
+
198
+ .sti-OrgSwitcher-empty-0c82b {
91
199
  padding: var(--sti-space-3);
92
200
  color: var(--sti-fg-muted);
93
201
  font-size: var(--sti-font-size-sm);
@@ -97,13 +205,17 @@
97
205
  }
98
206
 
99
207
  @media (forced-colors: active) {
100
- .sti-OrgSwitcher-trigger-8cf9a[data-focus-visible] {
208
+ .sti-OrgSwitcher-mark-a5082 {
209
+ border: var(--sti-border-width) solid CanvasText;
210
+ }
211
+
212
+ .sti-OrgSwitcher-createRow-c2255[data-focus-visible], .sti-OrgSwitcher-trigger-0f64d[data-focus-visible] {
101
213
  outline-color: highlight;
102
214
  }
103
215
  }
104
216
 
105
217
  @media (prefers-reduced-motion: reduce) {
106
- .sti-OrgSwitcher-trigger-8cf9a {
218
+ .sti-OrgSwitcher-trigger-0f64d {
107
219
  transition: none;
108
220
  }
109
221
  }
@@ -10,14 +10,33 @@ export interface OrgSwitcherOrg {
10
10
  description?: string;
11
11
  avatarSrc?: string;
12
12
  }
13
+ export interface OrgSwitcherPanelProps {
14
+ orgs: readonly OrgSwitcherOrg[];
15
+ /** Seçili kuruluşun anahtarı. */
16
+ value?: string | null;
17
+ /** Bir kuruluş seçildiğinde. */
18
+ onSelect?: (id: string) => void;
19
+ /** Verilirse listenin altında "Yeni kuruluş oluşturun" satırı çıkar. */
20
+ onCreate?: () => void;
21
+ /** Verilirse "Yeni kuruluş oluşturun" bağlantıdır. */
22
+ createHref?: string;
23
+ /** Bu sayıdan çok kuruluş varsa arama alanı gösterilir. Varsayılan 7. */
24
+ searchThreshold?: number;
25
+ /** Açılınca odak arama alanına ya da ilk seçeneğe gider (açılır kutuda açık). */
26
+ autoFocus?: boolean;
27
+ className?: string;
28
+ id?: string;
29
+ }
13
30
  export interface OrgSwitcherProps {
14
31
  orgs: readonly OrgSwitcherOrg[];
15
32
  /** Seçili kuruluşun anahtarı (denetimli). */
16
33
  value?: string | null;
17
34
  defaultValue?: string | null;
18
35
  onChange?: (id: string) => void;
19
- /** Verilirse listenin altında "Yeni kuruluş oluşturun" düğmesi çıkar. */
36
+ /** Verilirse listenin altında "Yeni kuruluş oluşturun" satırı çıkar. */
20
37
  onCreate?: () => void;
38
+ /** Verilirse "Yeni kuruluş oluşturun" bağlantıdır. */
39
+ createHref?: string;
21
40
  /** Bu sayıdan çok kuruluş varsa arama alanı gösterilir. Varsayılan 7. */
22
41
  searchThreshold?: number;
23
42
  size?: "sm" | "md" | "lg";
@@ -30,8 +49,14 @@ export interface OrgSwitcherProps {
30
49
  id?: string;
31
50
  }
32
51
  /**
33
- * Kuruluş değiştirici: geçerli firma ya da müşteriyi gösteren düğme ve altında aranabilir seçim
34
- * listesi. Kuruluşlar türüne göre gruplanır. APG Listbox (tek seçim) açılır kutuda: oklar gezer,
35
- * Home ve End uçlara gider, harfle arama yapılır, Enter seçer ve kapatır, Escape vazgeçer.
52
+ * Kuruluş listesi: isteğe bağlı arama alanı, türe göre gruplu tek seçimli liste (APG Listbox) ve
53
+ * "Yeni kuruluş oluşturun" satırı. `OrgSwitcher` bunu açılır kutuda çizer; uygulama yan menüde ya da
54
+ * kuruluş seçim sayfasında doğrudan kullanabilir.
55
+ */
56
+ export declare function OrgSwitcherPanel({ orgs, value, onSelect, onCreate, createHref, searchThreshold, autoFocus, className, id }: OrgSwitcherPanelProps): import("react").JSX.Element;
57
+ /**
58
+ * Kuruluş değiştirici: geçerli firma ya da müşteriyi gösteren düğme ve altında kuruluş listesi
59
+ * (`OrgSwitcherPanel`). APG Listbox (tek seçim) açılır kutuda: oklar gezer, Home ve End uçlara
60
+ * gider, harfle arama yapılır, Enter seçer ve kapatır, Escape vazgeçer.
36
61
  */
37
- export declare function OrgSwitcher({ orgs, value, defaultValue, onChange, onCreate, searchThreshold, size, placement, isDisabled, isOpen, defaultOpen, onOpenChange, className, id }: OrgSwitcherProps): import("react").JSX.Element;
62
+ export declare function OrgSwitcher({ orgs, value, defaultValue, onChange, onCreate, createHref, searchThreshold, size, placement, isDisabled, isOpen, defaultOpen, onOpenChange, className, id }: OrgSwitcherProps): import("react").JSX.Element;
@@ -4,8 +4,7 @@ import { template } from "../../text/text.js";
4
4
  import listbox_module_default from "../../components/_internal/listbox/listbox.module.js";
5
5
  import { renderOptions } from "../../components/_internal/listbox/options.js";
6
6
  import { VisuallyHidden } from "../../components/VisuallyHidden/VisuallyHidden.js";
7
- import { Button as Button$1 } from "../../components/Button/Button.js";
8
- import { Avatar } from "../../components/Avatar/Avatar.js";
7
+ import { Avatar, avatarColorOf } from "../../components/Avatar/Avatar.js";
9
8
  import { SearchField as SearchField$1 } from "../../components/SearchField/SearchField.js";
10
9
  import { Popover as Popover$1 } from "../../components/Popover/Popover.js";
11
10
  import { PlusIcon } from "../../icons/generated/PlusIcon.js";
@@ -15,21 +14,38 @@ import { ChevronsUpDownIcon } from "../../icons/generated/ChevronsUpDownIcon.js"
15
14
  import OrgSwitcher_module_default from "./OrgSwitcher.module.js";
16
15
  import { jsx, jsxs } from "react/jsx-runtime";
17
16
  import { useMemo, useState } from "react";
18
- import { Button, ListBox } from "react-aria-components";
17
+ import { Button, Link, ListBox } from "react-aria-components";
19
18
  // src/id/OrgSwitcher/OrgSwitcher.tsx
20
19
  const fold = (s, locale) => s.toLocaleLowerCase(locale);
21
20
  /**
22
- * Kuruluş değiştirici: geçerli firma ya da müşteriyi gösteren düğme ve altında aranabilir seçim
23
- * listesi. Kuruluşlar türüne göre gruplanır. APG Listbox (tek seçim) açılır kutuda: oklar gezer,
24
- * Home ve End uçlara gider, harfle arama yapılır, Enter seçer ve kapatır, Escape vazgeçer.
21
+ * Kuruluş karosu (süs): fotoğraf varsa fotoğraf, yoksa türün ikonu (firma bina, müşteri çanta)
22
+ * kuruluşa göre kalıcı renkli karoda. Harf yazılmaz: seçeneğin adı görünür metinle çelişmez.
25
23
  */
26
- function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, searchThreshold = 7, size = "md", placement = "bottom start", isDisabled, isOpen, defaultOpen, onOpenChange, className, id }) {
24
+ function OrgMark({ org, size = "sm" }) {
25
+ if (org.avatarSrc) return /* @__PURE__ */ jsx(Avatar, {
26
+ name: org.name,
27
+ src: org.avatarSrc,
28
+ size: size === "md" ? "sm" : "xs",
29
+ shape: "square",
30
+ isDecorative: true
31
+ });
32
+ return /* @__PURE__ */ jsx("span", {
33
+ className: OrgSwitcher_module_default.mark,
34
+ "data-size": size,
35
+ "data-color": avatarColorOf(org.id),
36
+ "aria-hidden": "true",
37
+ children: org.kind === "company" ? /* @__PURE__ */ jsx(BuildingIcon, {}) : /* @__PURE__ */ jsx(BriefcaseIcon, {})
38
+ });
39
+ }
40
+ /**
41
+ * Kuruluş listesi: isteğe bağlı arama alanı, türe göre gruplu tek seçimli liste (APG Listbox) ve
42
+ * "Yeni kuruluş oluşturun" satırı. `OrgSwitcher` bunu açılır kutuda çizer; uygulama yan menüde ya da
43
+ * kuruluş seçim sayfasında doğrudan kullanabilir.
44
+ */
45
+ function OrgSwitcherPanel({ orgs, value = null, onSelect, onCreate, createHref, searchThreshold = 7, autoFocus = false, className, id }) {
27
46
  const t = useMessages();
28
47
  const locale = useLocale();
29
- const [inner, setInner] = useState(defaultValue);
30
48
  const [query, setQuery] = useState("");
31
- const current = value === void 0 ? inner : value;
32
- const selected = orgs.find((o) => o.id === current);
33
49
  const showSearch = orgs.length > searchThreshold;
34
50
  const q = fold(query.trim(), locale);
35
51
  const items = useMemo(() => {
@@ -38,13 +54,7 @@ function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, sea
38
54
  id: o.id,
39
55
  label: o.name,
40
56
  description: o.description,
41
- icon: o.avatarSrc ? /* @__PURE__ */ jsx(Avatar, {
42
- name: o.name,
43
- src: o.avatarSrc,
44
- size: "xs",
45
- shape: "square",
46
- isDecorative: true
47
- }) : o.kind === "company" ? /* @__PURE__ */ jsx(BuildingIcon, {}) : /* @__PURE__ */ jsx(BriefcaseIcon, {})
57
+ icon: /* @__PURE__ */ jsx(OrgMark, { org: o })
48
58
  });
49
59
  const companies = visible.filter((o) => o.kind === "company");
50
60
  const clients = visible.filter((o) => o.kind === "client");
@@ -65,12 +75,73 @@ function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, sea
65
75
  t.idOrgKindCompany,
66
76
  t.idOrgKindClient
67
77
  ]);
68
- const pick = (key, close) => {
69
- setInner(key);
70
- onChange?.(key);
71
- setQuery("");
72
- close();
73
- };
78
+ return /* @__PURE__ */ jsxs("div", {
79
+ id,
80
+ className: [OrgSwitcher_module_default.body, className].filter(Boolean).join(" "),
81
+ children: [
82
+ showSearch ? /* @__PURE__ */ jsx(SearchField$1, {
83
+ label: t.idOrgSearch,
84
+ hideLabel: true,
85
+ placeholder: t.idOrgSearch,
86
+ size: "sm",
87
+ value: query,
88
+ onChange: setQuery,
89
+ autoFocus
90
+ }) : null,
91
+ /* @__PURE__ */ jsx("div", {
92
+ className: OrgSwitcher_module_default.scroll,
93
+ children: /* @__PURE__ */ jsx(ListBox, {
94
+ "aria-label": t.idOrgList,
95
+ className: listbox_module_default.list,
96
+ selectionMode: "single",
97
+ disallowEmptySelection: true,
98
+ selectedKeys: value ? [value] : [],
99
+ autoFocus: autoFocus && !showSearch ? "first" : void 0,
100
+ onSelectionChange: (keys) => {
101
+ const key = keys === "all" ? void 0 : [...keys][0];
102
+ if (key === void 0) return;
103
+ setQuery("");
104
+ onSelect?.(String(key));
105
+ },
106
+ renderEmptyState: () => /* @__PURE__ */ jsx("p", {
107
+ className: OrgSwitcher_module_default.empty,
108
+ children: template(t.idOrgNoMatch, { query })
109
+ }),
110
+ children: renderOptions(items)
111
+ })
112
+ }),
113
+ onCreate || createHref ? /* @__PURE__ */ jsx("div", {
114
+ className: OrgSwitcher_module_default.create,
115
+ children: createHref ? /* @__PURE__ */ jsxs(Link, {
116
+ className: OrgSwitcher_module_default.createRow,
117
+ href: createHref,
118
+ onPress: onCreate,
119
+ children: [/* @__PURE__ */ jsx(PlusIcon, {
120
+ className: OrgSwitcher_module_default.createIcon,
121
+ "aria-hidden": "true"
122
+ }), t.idOrgCreate]
123
+ }) : /* @__PURE__ */ jsxs(Button, {
124
+ className: OrgSwitcher_module_default.createRow,
125
+ onPress: onCreate,
126
+ children: [/* @__PURE__ */ jsx(PlusIcon, {
127
+ className: OrgSwitcher_module_default.createIcon,
128
+ "aria-hidden": "true"
129
+ }), t.idOrgCreate]
130
+ })
131
+ }) : null
132
+ ]
133
+ });
134
+ }
135
+ /**
136
+ * Kuruluş değiştirici: geçerli firma ya da müşteriyi gösteren düğme ve altında kuruluş listesi
137
+ * (`OrgSwitcherPanel`). APG Listbox (tek seçim) açılır kutuda: oklar gezer, Home ve End uçlara
138
+ * gider, harfle arama yapılır, Enter seçer ve kapatır, Escape vazgeçer.
139
+ */
140
+ function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, createHref, searchThreshold = 7, size = "md", placement = "bottom start", isDisabled, isOpen, defaultOpen, onOpenChange, className, id }) {
141
+ const t = useMessages();
142
+ const [inner, setInner] = useState(defaultValue);
143
+ const current = value === void 0 ? inner : value;
144
+ const selected = orgs.find((o) => o.id === current);
74
145
  return /* @__PURE__ */ jsx(Popover$1, {
75
146
  placement,
76
147
  "aria-label": t.idOrgSwitcher,
@@ -78,23 +149,14 @@ function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, sea
78
149
  className: OrgSwitcher_module_default.card,
79
150
  isOpen,
80
151
  defaultOpen,
81
- onOpenChange: (open) => {
82
- if (!open) setQuery("");
83
- onOpenChange?.(open);
84
- },
152
+ onOpenChange,
85
153
  trigger: /* @__PURE__ */ jsxs(Button, {
86
154
  id,
87
155
  className: [OrgSwitcher_module_default.trigger, className].filter(Boolean).join(" "),
88
156
  "data-size": size,
89
157
  isDisabled,
90
158
  children: [
91
- selected ? /* @__PURE__ */ jsx(Avatar, {
92
- name: selected.name,
93
- src: selected.avatarSrc,
94
- size: "xs",
95
- shape: "square",
96
- isDecorative: true
97
- }) : null,
159
+ selected ? /* @__PURE__ */ jsx(OrgMark, { org: selected }) : null,
98
160
  selected ? /* @__PURE__ */ jsxs(VisuallyHidden, { children: [t.idOrgSwitcherCurrent, ": "] }) : null,
99
161
  /* @__PURE__ */ jsx("span", {
100
162
  className: OrgSwitcher_module_default.name,
@@ -106,48 +168,22 @@ function OrgSwitcher({ orgs, value, defaultValue = null, onChange, onCreate, sea
106
168
  })
107
169
  ]
108
170
  }),
109
- footer: onCreate ? (close) => /* @__PURE__ */ jsx(Button$1, {
110
- variant: "ghost",
111
- size: "sm",
112
- fullWidth: true,
113
- iconStart: /* @__PURE__ */ jsx(PlusIcon, {}),
114
- onPress: () => {
171
+ children: (close) => /* @__PURE__ */ jsx(OrgSwitcherPanel, {
172
+ orgs,
173
+ value: current,
174
+ searchThreshold,
175
+ autoFocus: true,
176
+ createHref,
177
+ onCreate: onCreate ? () => {
115
178
  close();
116
179
  onCreate();
117
- },
118
- children: t.idOrgCreate
119
- }) : void 0,
120
- children: (close) => /* @__PURE__ */ jsxs("div", {
121
- className: OrgSwitcher_module_default.body,
122
- children: [showSearch ? /* @__PURE__ */ jsx(SearchField$1, {
123
- label: t.idOrgSearch,
124
- hideLabel: true,
125
- placeholder: t.idOrgSearch,
126
- size: "sm",
127
- value: query,
128
- onChange: setQuery,
129
- autoFocus: true
130
- }) : null, /* @__PURE__ */ jsx("div", {
131
- className: OrgSwitcher_module_default.scroll,
132
- children: /* @__PURE__ */ jsx(ListBox, {
133
- "aria-label": t.idOrgList,
134
- className: listbox_module_default.list,
135
- selectionMode: "single",
136
- disallowEmptySelection: true,
137
- selectedKeys: current ? [current] : [],
138
- autoFocus: showSearch ? false : "first",
139
- onSelectionChange: (keys) => {
140
- const key = keys === "all" ? void 0 : [...keys][0];
141
- if (key !== void 0) pick(String(key), close);
142
- },
143
- renderEmptyState: () => /* @__PURE__ */ jsx("p", {
144
- className: OrgSwitcher_module_default.empty,
145
- children: template(t.idOrgNoMatch, { query })
146
- }),
147
- children: renderOptions(items)
148
- })
149
- })]
180
+ } : void 0,
181
+ onSelect: (key) => {
182
+ setInner(key);
183
+ onChange?.(key);
184
+ close();
185
+ }
150
186
  })
151
187
  });
152
188
  }
153
- export { OrgSwitcher };
189
+ export { OrgSwitcher, OrgSwitcherPanel };
@@ -1,12 +1,16 @@
1
1
  import './OrgSwitcher.css';
2
2
  // src/id/OrgSwitcher/OrgSwitcher.module.css
3
3
  var OrgSwitcher_module_default = {
4
- "trigger": "sti-OrgSwitcher-trigger-8cf9a",
5
- "name": "sti-OrgSwitcher-name-0b2eb",
6
- "chevron": "sti-OrgSwitcher-chevron-e70b6",
7
- "card": "sti-OrgSwitcher-card-297cc",
8
- "body": "sti-OrgSwitcher-body-e5f5e",
9
- "scroll": "sti-OrgSwitcher-scroll-eca85",
10
- "empty": "sti-OrgSwitcher-empty-1d36a"
4
+ "trigger": "sti-OrgSwitcher-trigger-0f64d",
5
+ "name": "sti-OrgSwitcher-name-c202c",
6
+ "mark": "sti-OrgSwitcher-mark-a5082",
7
+ "chevron": "sti-OrgSwitcher-chevron-d6eea",
8
+ "card": "sti-OrgSwitcher-card-af900",
9
+ "body": "sti-OrgSwitcher-body-dd131",
10
+ "scroll": "sti-OrgSwitcher-scroll-045d7",
11
+ "create": "sti-OrgSwitcher-create-8b4bd",
12
+ "createRow": "sti-OrgSwitcher-createRow-c2255",
13
+ "createIcon": "sti-OrgSwitcher-createIcon-a21cc",
14
+ "empty": "sti-OrgSwitcher-empty-0c82b"
11
15
  };
12
16
  export { OrgSwitcher_module_default as default };
@@ -1,2 +1,2 @@
1
- import { OrgSwitcher, OrgSwitcherOrg, OrgSwitcherProps } from "./OrgSwitcher.js";
2
- export { OrgSwitcher, OrgSwitcherOrg, OrgSwitcherProps };
1
+ import { OrgSwitcher, OrgSwitcherOrg, OrgSwitcherPanel, OrgSwitcherPanelProps, OrgSwitcherProps } from "./OrgSwitcher.js";
2
+ export { OrgSwitcher, OrgSwitcherOrg, OrgSwitcherPanel, OrgSwitcherPanelProps, OrgSwitcherProps };
@@ -1,12 +1,12 @@
1
1
  @layer sti.reset, sti.tokens, sti.base, sti.components, sti.variants, sti.utilities;
2
2
  @layer sti.components {
3
- .sti-PermissionGate-root-bf743 {
3
+ .sti-PermissionGate-root-5f706 {
4
4
  align-items: flex-start;
5
5
  gap: var(--sti-space-3);
6
6
  box-sizing: border-box;
7
7
  min-inline-size: 0;
8
- padding: var(--sti-space-4) var(--sti-space-5);
9
- border: var(--sti-border-width) dashed var(--sti-border);
8
+ padding: var(--sti-space-5);
9
+ border: var(--sti-border-width) solid var(--sti-border-subtle);
10
10
  border-radius: var(--sti-radius-lg);
11
11
  background: var(--sti-bg-subtle);
12
12
  color: var(--sti-fg);
@@ -14,26 +14,33 @@
14
14
  display: flex;
15
15
  }
16
16
 
17
- .sti-PermissionGate-icon-01cb9 {
18
- inline-size: var(--sti-control-h-sm);
19
- block-size: var(--sti-control-h-sm);
20
- border-radius: var(--sti-radius-pill);
21
- background: var(--sti-bg-surface-active);
22
- color: var(--sti-fg-muted);
17
+ .sti-PermissionGate-icon-c225d {
18
+ inline-size: var(--sti-control-h-md);
19
+ block-size: var(--sti-control-h-md);
20
+ border-radius: var(--sti-radius-md);
21
+ background: var(--sti-bg-warning-subtle);
22
+ color: var(--sti-fg-warning-strong);
23
23
  font-size: var(--sti-icon-md);
24
24
  flex: none;
25
25
  place-items: center;
26
26
  display: inline-grid;
27
27
  }
28
28
 
29
- .sti-PermissionGate-text-4385b {
29
+ .sti-PermissionGate-text-3358e {
30
30
  gap: var(--sti-space-1);
31
31
  min-inline-size: 0;
32
- padding-block-start: var(--sti-space-1);
32
+ padding-block-start: var(--sti-space-2);
33
33
  display: grid;
34
34
  }
35
35
 
36
- .sti-PermissionGate-title-074a4 {
36
+ .sti-PermissionGate-action-69333 {
37
+ gap: var(--sti-space-2);
38
+ flex-wrap: wrap;
39
+ margin-block-start: var(--sti-space-2);
40
+ display: flex;
41
+ }
42
+
43
+ .sti-PermissionGate-title-9e7ef {
37
44
  font-size: var(--sti-font-size-md);
38
45
  font-weight: var(--sti-font-weight-semibold);
39
46
  line-height: var(--sti-line-height-md);
@@ -41,7 +48,7 @@
41
48
  margin: 0;
42
49
  }
43
50
 
44
- .sti-PermissionGate-description-c623a {
51
+ .sti-PermissionGate-description-3002e {
45
52
  color: var(--sti-fg-muted);
46
53
  font-size: var(--sti-font-size-sm);
47
54
  line-height: var(--sti-line-height-sm);
@@ -50,8 +57,12 @@
50
57
  }
51
58
 
52
59
  @media (forced-colors: active) {
53
- .sti-PermissionGate-root-bf743 {
60
+ .sti-PermissionGate-root-5f706 {
54
61
  border-color: canvastext;
55
62
  }
63
+
64
+ .sti-PermissionGate-icon-c225d {
65
+ border: var(--sti-border-width) solid CanvasText;
66
+ }
56
67
  }
57
68
  }
@@ -18,6 +18,8 @@ export interface PermissionGateProps {
18
18
  denied?: ReactNode;
19
19
  /** `denied` ile birlikte kısa başlık ("Erişim yetkisi gerekli"). */
20
20
  deniedTitle?: ReactNode;
21
+ /** Yetki açıklamasının altındaki eylem ("Yetki isteyin" düğmesi ya da bağlantısı). */
22
+ deniedAction?: ReactNode;
21
23
  children: ReactNode;
22
24
  className?: string;
23
25
  id?: string;
@@ -27,4 +29,4 @@ export interface PermissionGateProps {
27
29
  * açıklamasını. Yalnız GÖRÜNÜMÜ düzenler; yetki denetimi her zaman sunucuda yeniden yapılmalıdır.
28
30
  * Sunucu bileşenidir.
29
31
  */
30
- export declare function PermissionGate({ granted, require, match, fallback, denied, deniedTitle, children, className, id }: PermissionGateProps): import("react").JSX.Element | null;
32
+ export declare function PermissionGate({ granted, require, match, fallback, denied, deniedTitle, deniedAction, children, className, id }: PermissionGateProps): import("react").JSX.Element | null;