@apliteni/apliteni-ui 0.56.0 → 0.56.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apliteni/apliteni-ui",
3
- "version": "0.56.0",
3
+ "version": "0.56.1",
4
4
  "workspaces": [
5
5
  "react"
6
6
  ],
@@ -68,6 +68,8 @@
68
68
  border-bottom: 1px solid var(--border);
69
69
  }
70
70
  .rx-modal__title {
71
+ margin: 0;
72
+ font-family: var(--font-sans);
71
73
  font-weight: var(--weight-normal);
72
74
  font-size: var(--text-base);
73
75
  color: var(--text);
@@ -14,6 +14,8 @@ type ButtonProps = {
14
14
  block?: boolean;
15
15
  /** In flight: keeps focus, blocks activation, announces progress, and shows dots. */
16
16
  busy?: boolean;
17
+ /** Message after busy ends; an empty string leaves outcome announcements to the caller. */
18
+ completionMessage?: string;
17
19
  children?: ReactNode;
18
20
  } & ButtonHTMLAttributes<HTMLButtonElement>;
19
21
  declare const Button: react.ForwardRefExoticComponent<{
@@ -25,6 +27,8 @@ declare const Button: react.ForwardRefExoticComponent<{
25
27
  block?: boolean;
26
28
  /** In flight: keeps focus, blocks activation, announces progress, and shows dots. */
27
29
  busy?: boolean;
30
+ /** Message after busy ends; an empty string leaves outcome announcements to the caller. */
31
+ completionMessage?: string;
28
32
  children?: ReactNode;
29
33
  } & ButtonHTMLAttributes<HTMLButtonElement> & react.RefAttributes<HTMLButtonElement>>;
30
34
 
@@ -56,6 +56,7 @@ var Button = forwardRef(function Button2({
56
56
  iconOnly,
57
57
  block,
58
58
  busy,
59
+ completionMessage,
59
60
  children,
60
61
  type = "button",
61
62
  disabled,
@@ -83,7 +84,7 @@ var Button = forwardRef(function Button2({
83
84
  const prior = previous.current;
84
85
  if ((busy || prior?.busy) && (!prior || prior.text !== text2 || prior.busy !== busy)) {
85
86
  announcer.current ?? (announcer.current = acquireAnnouncer(buttonRef.current.ownerDocument));
86
- announcer.current.announce(`${text2}: ${busy ? "in progress" : "complete"}`);
87
+ announcer.current.announce(busy ? `${text2}: in progress` : completionMessage ?? `${text2}: complete`);
87
88
  }
88
89
  previous.current = { text: text2, busy };
89
90
  });
@@ -472,7 +473,7 @@ function Modal({ open, title, onClose, footer, children, initialFocusRef, role =
472
473
  ref: panel,
473
474
  children: [
474
475
  /* @__PURE__ */ jsxs5("div", { className: "rx-modal__head", children: [
475
- /* @__PURE__ */ jsx7("div", { className: "rx-modal__title", id: titleId, children: title }),
476
+ /* @__PURE__ */ jsx7("h2", { className: "rx-modal__title", id: titleId, children: title }),
476
477
  /* @__PURE__ */ jsx7(Button, { variant: "ghost", size: "sm", iconOnly: true, icon: "x", "aria-label": "Close", onClick: onClose })
477
478
  ] }),
478
479
  /* @__PURE__ */ jsx7("div", { className: "rx-modal__body", id: bodyId, ref: body, children }),
@@ -1943,6 +1944,9 @@ function Timeline({ events, className, ...rest }) {
1943
1944
  import { useEffect as useEffect8, useId as useId8, useRef as useRef13, useState as useState7 } from "react";
1944
1945
  import { esc, icon as icon4 } from "@apliteni/apliteni-ui";
1945
1946
  import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
1947
+ function messages(id, hint, error) {
1948
+ return [error && `${id}-error`, hint && `${id}-hint`].filter(Boolean).join(" ") || void 0;
1949
+ }
1946
1950
  function Frame({ id, label, hint, error, required, children }) {
1947
1951
  return /* @__PURE__ */ jsxs19("div", { className: "ui-field", children: [
1948
1952
  /* @__PURE__ */ jsxs19("label", { className: "ui-field__label", htmlFor: id, children: [
@@ -1950,23 +1954,25 @@ function Frame({ id, label, hint, error, required, children }) {
1950
1954
  required && /* @__PURE__ */ jsx23("span", { className: "ui-field__req", "aria-hidden": "true", children: "*" })
1951
1955
  ] }),
1952
1956
  children,
1953
- (error || hint) && /* @__PURE__ */ jsx23(
1957
+ error && /* @__PURE__ */ jsx23(
1954
1958
  "div",
1955
1959
  {
1956
- id: `${id}-message`,
1957
- className: error ? "ui-field__error" : "ui-field__hint",
1958
- dangerouslySetInnerHTML: { __html: (error ? icon4("alert") : "") + esc(error || hint) }
1960
+ id: `${id}-error`,
1961
+ className: "ui-field__error",
1962
+ role: "alert",
1963
+ dangerouslySetInnerHTML: { __html: icon4("alert") + esc(error) }
1959
1964
  }
1960
- )
1965
+ ),
1966
+ hint && /* @__PURE__ */ jsx23("div", { id: `${id}-hint`, className: "ui-field__hint", children: hint })
1961
1967
  ] });
1962
1968
  }
1963
1969
  function wiring(id, hint, error) {
1964
- return { id, "aria-describedby": error || hint ? `${id}-message` : void 0, "aria-invalid": error ? true : void 0 };
1970
+ return { id, "aria-describedby": messages(id, hint, error), "aria-invalid": error ? true : void 0 };
1965
1971
  }
1966
1972
  function TextField({ label, hint, error, required, type = "text", unit, className = "", ...props }) {
1967
1973
  const id = useId8();
1968
1974
  const hasUnit = type === "number" && !!unit;
1969
- const describedBy = [error || hint ? `${id}-message` : "", hasUnit ? `${id}-unit` : ""].filter(Boolean).join(" ") || void 0;
1975
+ const describedBy = [messages(id, hint, error), hasUnit ? `${id}-unit` : ""].filter(Boolean).join(" ") || void 0;
1970
1976
  const control = /* @__PURE__ */ jsx23(
1971
1977
  "input",
1972
1978
  {
@@ -2074,7 +2080,7 @@ function FileField({ label, hint, error, required, disabled, onFileChange, class
2074
2080
  }
2075
2081
 
2076
2082
  // src/Toast.tsx
2077
- import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect9, useRef as useRef14, useState as useState8 } from "react";
2083
+ import { createContext as createContext2, useCallback as useCallback3, useContext as useContext2, useEffect as useEffect9, useLayoutEffect as useLayoutEffect4, useRef as useRef14, useState as useState8 } from "react";
2078
2084
  import { createPortal as createPortal4 } from "react-dom";
2079
2085
  import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
2080
2086
  var Context = createContext2(null);
@@ -2169,18 +2175,40 @@ function Notice({ notice, remove }) {
2169
2175
  }
2170
2176
  );
2171
2177
  }
2178
+ var REACH = "--rx-toast-stack";
2179
+ function usePublishedReach(stack2, count) {
2180
+ useLayoutEffect4(() => {
2181
+ const element = stack2.current;
2182
+ const view = element?.ownerDocument.defaultView;
2183
+ const root = element?.ownerDocument.documentElement;
2184
+ if (!element || !view || !root) return;
2185
+ const publish = () => {
2186
+ const box = element.getBoundingClientRect();
2187
+ root.style.setProperty(REACH, `${box.height ? Math.round(view.innerHeight - box.top) : 0}px`);
2188
+ };
2189
+ publish();
2190
+ const observer = typeof view.ResizeObserver === "function" ? new view.ResizeObserver(publish) : void 0;
2191
+ observer?.observe(element);
2192
+ return () => {
2193
+ observer?.disconnect();
2194
+ root.style.removeProperty(REACH);
2195
+ };
2196
+ }, [stack2, count]);
2197
+ }
2172
2198
  function Toast({ children }) {
2173
2199
  const [entries, setEntries] = useState8([]);
2174
2200
  const nextId = useRef14(0);
2201
+ const stack2 = useRef14(null);
2175
2202
  const push = useCallback3((notice) => {
2176
2203
  const id = nextId.current++;
2177
2204
  const remove = () => setEntries((current) => current.filter((entry) => entry.id !== id));
2178
2205
  setEntries((current) => [...current, { id, notice, remove }]);
2179
2206
  }, []);
2207
+ usePublishedReach(stack2, entries.length);
2180
2208
  return /* @__PURE__ */ jsxs20(Context.Provider, { value: push, children: [
2181
2209
  children,
2182
2210
  typeof document !== "undefined" && createPortal4(
2183
- /* @__PURE__ */ jsx24("div", { className: "ui-toast-stack rx-toast-stack", children: entries.map((entry) => /* @__PURE__ */ jsx24(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
2211
+ /* @__PURE__ */ jsx24("div", { className: "ui-toast-stack rx-toast-stack", ref: stack2, children: entries.map((entry) => /* @__PURE__ */ jsx24(Notice, { notice: entry.notice, remove: entry.remove }, entry.id)) }),
2184
2212
  document.body
2185
2213
  )
2186
2214
  ] });