@moontra/moonui 6.16.0 → 6.18.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/dist/index.js CHANGED
@@ -4099,23 +4099,49 @@ function DataTableBasic({
4099
4099
  ] }) }),
4100
4100
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded-md border", children: /* @__PURE__ */ jsxRuntime.jsxs(Table, { children: [
4101
4101
  /* @__PURE__ */ jsxRuntime.jsx(TableHeader, { children: table.getHeaderGroups().map((headerGroup) => /* @__PURE__ */ jsxRuntime.jsx(TableRow, { children: headerGroup.headers.map((header) => {
4102
- return /* @__PURE__ */ jsxRuntime.jsx(TableHead, { children: header.isPlaceholder ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4103
- "div",
4102
+ const canSort = enableSorting && header.column.getCanSort();
4103
+ const sorted = header.column.getIsSorted();
4104
+ const headerDef = header.column.columnDef.header;
4105
+ return /* @__PURE__ */ jsxRuntime.jsx(
4106
+ TableHead,
4104
4107
  {
4105
- className: cn(
4106
- "flex items-center gap-2",
4107
- header.column.getCanSort() && "cursor-pointer select-none"
4108
- ),
4109
- onClick: header.column.getToggleSortingHandler(),
4110
- children: [
4111
- reactTable.flexRender(
4112
- header.column.columnDef.header,
4113
- header.getContext()
4114
- ),
4115
- enableSorting && header.column.getCanSort() && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "ml-auto", children: header.column.getIsSorted() === "desc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-4 w-4" }) : header.column.getIsSorted() === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpDown, { className: "h-4 w-4 opacity-50" }) })
4116
- ]
4117
- }
4118
- ) }, header.id);
4108
+ "aria-sort": canSort ? sorted === "asc" ? "ascending" : sorted === "desc" ? "descending" : "none" : void 0,
4109
+ children: header.isPlaceholder ? null : /* @__PURE__ */ jsxRuntime.jsxs(
4110
+ "div",
4111
+ {
4112
+ className: cn(
4113
+ "flex items-center gap-2",
4114
+ canSort && "cursor-pointer select-none"
4115
+ ),
4116
+ onClick: canSort ? header.column.getToggleSortingHandler() : void 0,
4117
+ children: [
4118
+ reactTable.flexRender(
4119
+ header.column.columnDef.header,
4120
+ header.getContext()
4121
+ ),
4122
+ canSort && /* #366: sıralama kontrolü yalnız fareyle çalışıyordu
4123
+ (dosyada `tabIndex`/`onKeyDown` grep'i 0 idi).
4124
+ Gerçek <button> ile Tab + Enter/Space native
4125
+ gelir; görünür odak focus-visible ring ile. */
4126
+ /* @__PURE__ */ jsxRuntime.jsx(
4127
+ "button",
4128
+ {
4129
+ type: "button",
4130
+ onClick: (event) => {
4131
+ event.stopPropagation();
4132
+ header.column.getToggleSortingHandler()?.(event);
4133
+ },
4134
+ "aria-label": `Sort by ${typeof headerDef === "string" ? headerDef : header.column.id}`,
4135
+ className: "ml-auto inline-flex items-center rounded-sm outline-none focus-visible:ring-2 focus-visible:ring-ring",
4136
+ children: sorted === "desc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowDown, { className: "h-4 w-4" }) : sorted === "asc" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpDown, { className: "h-4 w-4 opacity-50" })
4137
+ }
4138
+ )
4139
+ ]
4140
+ }
4141
+ )
4142
+ },
4143
+ header.id
4144
+ );
4119
4145
  }) }, headerGroup.id)) }),
4120
4146
  /* @__PURE__ */ jsxRuntime.jsx(TableBody, { children: table.getRowModel().rows?.length ? table.getRowModel().rows.map((row) => /* @__PURE__ */ jsxRuntime.jsx(
4121
4147
  TableRow,
@@ -4883,7 +4909,20 @@ var progressIndicatorVariants = classVarianceAuthority.cva(
4883
4909
  variant: {
4884
4910
  default: "bg-foreground",
4885
4911
  primary: "bg-primary",
4886
- secondary: "bg-secondary",
4912
+ // #372: dolgu `bg-secondary` idi — track (`bg-secondary/20`) ile AYNI
4913
+ // yüzey token'ına basıyordu; %20 alfa track ile tam dolgu iki temada da
4914
+ // ~1.0 oranında kalıyor, bar görünmüyordu (light rgb(235,239,245) /
4915
+ // dark rgb(2,8,23)). `bg-secondary-foreground` BİLEREK seçilmedi:
4916
+ // light'ta --primary ile aynı hue/sat'ta yalnız ΔL=%2 (49 vs 51,
4917
+ // fill↔fill 1.07), dark'ta birebir --primary değeri (210 40% 98%) —
4918
+ // secondary varyantı primary'nin klonuna dönerdi. `--secondary-500`
4919
+ // (tokens.css slate skalası, RGB üçlüsü) iki temada da track'e ≥3:1
4920
+ // (WCAG 1.4.11) veren TEK kademe: light 4.63, dark 4.23 (gerçek kart
4921
+ // #111827 üstünde 3.83; 400 light'ta 2.50 ✗, 600 dark'ta 2.66 ✗).
4922
+ // Skala :root'ta tanımlı olduğundan tema değişiminde sabittir;
4923
+ // tüketici --secondary-500'ü ezerek özelleştirebilir.
4924
+ // Regresyon: __tests__/progress-secondary-contrast.test.ts
4925
+ secondary: "bg-[rgb(var(--secondary-500))]",
4887
4926
  success: "bg-success",
4888
4927
  warning: "bg-warning",
4889
4928
  error: "bg-error"
@@ -4977,6 +5016,26 @@ var formatFileSize = (bytes) => {
4977
5016
  const i = Math.floor(Math.log(bytes) / Math.log(k));
4978
5017
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
4979
5018
  };
5019
+ var matchesAcceptToken = (file, token) => {
5020
+ const normalized = token.trim().toLowerCase();
5021
+ if (!normalized)
5022
+ return false;
5023
+ if (normalized === "*" || normalized === "*/*")
5024
+ return true;
5025
+ if (normalized.startsWith(".")) {
5026
+ return file.name.toLowerCase().endsWith(normalized);
5027
+ }
5028
+ if (normalized.endsWith("/*")) {
5029
+ return file.type.toLowerCase().startsWith(normalized.slice(0, -1));
5030
+ }
5031
+ return file.type.toLowerCase() === normalized;
5032
+ };
5033
+ var isFileAccepted = (file, accept) => {
5034
+ const trimmed = accept.trim();
5035
+ if (trimmed === "" || trimmed === "*")
5036
+ return true;
5037
+ return trimmed.split(",").some((token) => matchesAcceptToken(file, token));
5038
+ };
4980
5039
  var FileItem = ({
4981
5040
  uploadedFile,
4982
5041
  onRemove
@@ -5055,13 +5114,7 @@ var FileUpload = React12__namespace.default.forwardRef(
5055
5114
  if (file.size > maxSize) {
5056
5115
  return `File size exceeds ${formatFileSize(maxSize)}`;
5057
5116
  }
5058
- if (accept !== "*" && !accept.split(",").some((type) => {
5059
- const cleanType = type.trim();
5060
- if (cleanType.includes("*")) {
5061
- return file.type.startsWith(cleanType.replace("*", ""));
5062
- }
5063
- return file.type === cleanType;
5064
- })) {
5117
+ if (!isFileAccepted(file, accept)) {
5065
5118
  return `File type not supported`;
5066
5119
  }
5067
5120
  return null;
@@ -5095,6 +5148,7 @@ var FileUpload = React12__namespace.default.forwardRef(
5095
5148
  preview: file.type.startsWith("image/") ? URL.createObjectURL(file) : void 0
5096
5149
  }));
5097
5150
  setUploadedFiles((prev) => [...prev, ...newUploadedFiles]);
5151
+ const progressIntervals = /* @__PURE__ */ new Map();
5098
5152
  for (const uploadedFile of newUploadedFiles) {
5099
5153
  let progress = 0;
5100
5154
  const interval = setInterval(() => {
@@ -5102,25 +5156,33 @@ var FileUpload = React12__namespace.default.forwardRef(
5102
5156
  if (progress >= 100) {
5103
5157
  progress = 100;
5104
5158
  clearInterval(interval);
5159
+ progressIntervals.delete(uploadedFile.id);
5105
5160
  setUploadedFiles(
5106
5161
  (prev) => prev.map(
5107
- (f) => f.id === uploadedFile.id ? { ...f, progress: 100, status: "success" } : f
5162
+ (f) => (
5163
+ // 'error'a düşmüş dosya simülasyonca geri 'success' yapılamaz —
5164
+ // error nihai durumdur (#378)
5165
+ f.id === uploadedFile.id && f.status === "uploading" ? { ...f, progress: 100, status: "success" } : f
5166
+ )
5108
5167
  )
5109
5168
  );
5110
5169
  } else {
5111
5170
  setUploadedFiles(
5112
5171
  (prev) => prev.map(
5113
- (f) => f.id === uploadedFile.id ? { ...f, progress } : f
5172
+ (f) => f.id === uploadedFile.id && f.status === "uploading" ? { ...f, progress } : f
5114
5173
  )
5115
5174
  );
5116
5175
  }
5117
5176
  }, 200);
5177
+ progressIntervals.set(uploadedFile.id, interval);
5118
5178
  }
5119
5179
  if (onUpload) {
5120
5180
  try {
5121
5181
  await onUpload(newUploadedFiles);
5122
5182
  } catch (error2) {
5123
5183
  console.error("Upload failed:", error2);
5184
+ progressIntervals.forEach((handle) => clearInterval(handle));
5185
+ progressIntervals.clear();
5124
5186
  setUploadedFiles(
5125
5187
  (prev) => prev.map(
5126
5188
  (f) => newUploadedFiles.some((nf) => nf.id === f.id) ? { ...f, status: "error" } : f